Pythonコード保管庫

コードに関しての質問はメールで対応します。

Tobii等の眼球運動計測装置を使用しない場合,乳児の注視行動を録画してあとからコーディングすることが多いと思います。

乳児がどのくらいある方向(ここでは左右あるいは上下)を見ているのか,ストップウォッチのように計測するPythonプラグラムです。

足りないパッケージ(import時)はpipなどでインストールしてください。

ここでは左右ですが好きな場所に合わせて作成可能です。

注視時間を計測するプログラム(選好注視用)

  1. 実行するとまず全部で何試行かを入力する。
  2. 左右矢印キーで左側と右側の注視時間を計測する。注視している間は矢印キーを押し続ける。見ていないときはキーを押さない。
  3. 左シフトキーを押して1試行の計測を終了する。
  4. 全試行終了したらEnterキーを押す。※他にコーディングするビデオがあれば続ける。なければEscapeキーを押してプログラムを終了する。
  5. 本プログラムを実行したフォルダに,(1)各試行におけるキー押し時間のローデータが保存されている”_row.csv”と,(2)各試行での左右それぞれの合計時間,サイドバイアスが計算された"_cal.csv"の2つが保存される。

#必要なモジュールをimportしておく

import time

import datetime

import pygame

from pygame.locals import *

import sys

import pandas as pd

import openpyxl

import tkinter


##########実験の試行数に合わせられるように試行数を打ち込むダイアログ呈示###########

root = tkinter.Tk()

root.title(u"Software Title")

root.geometry("400x300")


def nextstep(event):

  #エントリーの中身を削除

  #ここで,valueにEntryの中身が入る

  global trial

  trial = EditBox.get() #試行の数

  print(trial)

  root.destroy()


#エントリー

EditBox = tkinter.Entry(width=50)

EditBox.insert(tkinter.END,"試行数")

EditBox.pack()


#ボタン

Button = tkinter.Button(text=u'決定', width=50)

Button.bind("<Button-1>",nextstep) 

#左クリック(<Button-1>)されると,DeleteEntryValue関数を呼び出すようにバインド

Button.pack()


root.mainloop()

############################################################


pygame.init()

screen = pygame.display.set_mode((800, 600))    # 画面を作成

pygame.display.set_caption("Now coding...")    # タイトルを作成

font = pygame.font.Font(None, 55)


windowPresent = True

trial = int(trial)

flag = 0

################ここから注視時間計測を繰り返す###################

while windowPresent:    

    start_right = 0

    end_right = 0

    out_right = 0   

    start_left = 0

    end_left = 0

    out_left = 0

    

    waitingKeyPress = True

    count = 0

    

    results = []

    sumleft = []

    sumright = []

    sumout_left = []

    sumout_right = []

    

    testsumleft = []

    testsumright = []

    testsumout_left = []

    testsumout_right = []

    

    while waitingKeyPress:

        screen.fill((0, 0, 0)) 

        

        for event in pygame.event.get():

            if event.type == QUIT:

                pygame.quit()

                sys.exit()

            if event.type == KEYDOWN:  # キーを押したとき

                # ESCキーならスクリプトを終了

                if event.key == K_ESCAPE:

                    pygame.quit()

                    sys.exit()

                # 左シフトキーで試行を区切る#

                if event.key == K_LSHIFT:

                    results.append(["--------", "--------"])

                #=======Measurement stop=======================

                if event.key == K_RETURN:

                    sumleft.append(sum(sumout_left))

                    sumright.append(sum(sumout_right))

                    waitingKeyPress = False

                    d = datetime.datetime.today()

                    with pd.ExcelWriter(d.strftime("%Y%m%d%H%M")+ "_" +str(flag) +".xlsx") as writer: #excelに書き出し

                        row_results = pd.DataFrame(results, columns=["left","right"])

                        row_results.to_excel(writer, index = False, sheet_name="looking time") #average書き出し

                    ##################計算された値を保存############################

                    book=openpyxl.Workbook()

                    active_sheet = book.active

                    for f in range(1,(trial+1)):

                        active_sheet.cell(column=f*3, row=1, value=f) #試行数#

                        active_sheet.cell(column=f*3, row=2, value="right") 

                        active_sheet.cell(column=1+f*3, row=2, value="left")

                        active_sheet.cell(column=f*3, row=3, value=sumright[f-1])

                        active_sheet.cell(column=1+f*3, row=3, value=sumleft[f-1])

                        active_sheet.cell(column=2+f*3, row=3, value=sumright[f-1]+sumleft[f-1])

                    

                    

                    #############total###############

                    active_sheet.cell(column=3+f*3, row=2, value="total")

                    active_sheet.cell(column=3+f*3, row=3, value=sum(sumright[0:trial]+sumleft[0:trial]))

                    #############target###############

                    active_sheet.cell(column=4+f*3, row=2, value="target")

                    #############preference###############

                    active_sheet.cell(column=5+f*3, row=2, value="preference")

                    #############side bias#########

                    active_sheet.cell(column=6+f*3, row=2, value="side bias")

                    active_sheet.cell(column=6+f*3, row=3, value=sum(sumright[0:trial])/sum(sumright[0:trial]+sumleft[0:trial]))

                    #############chancel level######################

                    active_sheet.cell(column=7+f*3, row=2, value="chance level")

                    active_sheet.cell(column=7+f*3, row=3, value=0.5)

                    book.save(d.strftime("%Y%m%d%H%M")+ "_cal" + "_" +str(flag) +".xlsx")

                    flag += 1



                ################################

                # それぞれのキー押しについて時間を計算

                if event.key == K_LEFT:

                    start_left = time.perf_counter()

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[0,0])

                    print("押されたキー = " + pygame.key.name(event.key))

                    pygame.display.update()  

                if event.key == K_RIGHT:

                    start_right = time.perf_counter()

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[300,0])

                    print("押されたキー = " + pygame.key.name(event.key))

                    pygame.display.update()

            if event.type == KEYUP: #キーを離したとき

                if event.key == K_LEFT:

                    end_left = time.perf_counter()

                    out_left = (end_left - start_left)*1000

                    results.append([out_left,0])

                    sumout_left.append(out_left)

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[0,30])

                    print("離したキー = " + pygame.key.name(event.key) + ":" + str(out_left))

                    pygame.display.update()  

                if event.key == K_RIGHT:

                    end_right = time.perf_counter()

                    out_right = (end_right - start_right)*1000

                    results.append([0,out_right])

                    sumout_right.append(out_right)

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[300,30])

                    print("離したキー = " + pygame.key.name(event.key) + ":" + str(out_right))

                    pygame.display.update()

                if event.key == K_LSHIFT and count < trial:

                    sumleft.append(sum(sumout_left))

                    sumright.append(sum(sumout_right))

                    sumout_left = []

                    sumout_right = []

                    text = font.render("Next trial", True,(255,255,255))

                    screen.blit(text,[150,0])

                    print("Next" + pygame.key.name(event.key))

                    pygame.display.update()

                    count += 1

                    print(count)

             

pygame.quit()

sys.exit()

注視時間を計測するプログラム(馴化用)

基本は選好注視用と同じです。コード内に馴化試行の回数とテスト試行の回数をあらかじめ記載してください。

  1. 左右矢印キーで左側と右側の注視時間を計測する。注視している間は矢印キーを押し続ける。見ていないときはキーを押さない。
  2. 左シフトキーを押して1試行の計測を終了する。
  3. 全試行終了したらEnterキーを押す。※他にコーディングするビデオがあれば続ける。なければEscapeキーを押してプログラムを終了する。
  4. 本プログラムを実行したフォルダに,(1)各試行におけるキー押し時間のローデータが保存されている”_row.csv”と,(2)各試行での左右それぞれの合計時間,サイドバイアスが計算された"_cal.csv"の2つが保存される。

import time

import datetime

import pygame

from pygame.locals import *

import sys

import pandas as pd

import openpyxl



pygame.init()

screen = pygame.display.set_mode((800, 600))    # 画面を作成

pygame.display.set_caption("Now coding...")    # タイトルを作成

font = pygame.font.Font(None, 55)


windowPresent = True


trial = 6 #馴化試行の数

testtrial = 2

maximun_duration = 10000


flag = 0

while windowPresent:

    start_right = 0

    end_right = 0

    out_right = 0

    start_left = 0

    end_left = 0

    out_left = 0

    

    waitingKeyPress = True

    count = 0

    

    results = []

    sumleft = []

    sumright = []

    sumout_left = []

    sumout_right = []

    

    testsumleft = []

    testsumright = []

    testsumout_left = []

    testsumout_right = []

    

    while waitingKeyPress:

        screen.fill((0, 0, 0)) 

        

        for event in pygame.event.get():

            if event.type == QUIT:

                pygame.quit()

                sys.exit()

            if event.type == KEYDOWN:  # キーを押したとき

                # ESCキーならスクリプトを終了

                if event.key == K_ESCAPE:

                    pygame.quit()

                    sys.exit()

                # 左シフトキーで試行を区切る#

                if event.key == K_LSHIFT:

                    results.append(["--------", "--------"])

                #=======Measurement stop=======================

                if event.key == K_RETURN:

                    waitingKeyPress = False

                    d = datetime.datetime.today()

                    with pd.ExcelWriter(d.strftime("%Y%m%d%H%M")+ "_" +str(flag) +".xlsx") as writer: #excelに書き出し

                        row_results = pd.DataFrame(results, columns=["left","right"])

                        row_results.to_excel(writer, index = False, sheet_name="looking time") #average書き出し

                    ###########################計算された値を保存################################

                    book=openpyxl.Workbook()

                    active_sheet = book.active

                    for f in range(1, (trial+1)):

                        active_sheet.cell(column=f*3, row=1, value=f) #試行数#

                        active_sheet.cell(column=f*3, row=2, value="right") 

                        active_sheet.cell(column=1+f*3, row=2, value="left")

                        active_sheet.cell(column=f*3, row=3, value=sumright[f-1])

                        active_sheet.cell(column=1+f*3, row=3, value=sumleft[f-1])

                        active_sheet.cell(column=2+f*3, row=3, value=sumright[f-1]+sumleft[f-1])

                    f = f*3+3

                    for g in range(testtrial):

                        active_sheet.cell(column=f+g*3, row=1, value="test"+str(g+1)) #試行数#

                        active_sheet.cell(column=f+g*3, row=2, value="right") 

                        active_sheet.cell(column=f+g*3+1, row=2, value="left")

                        active_sheet.cell(column=f+g*3, row=3, value=testsumright[g])

                        active_sheet.cell(column=f+g*3+1, row=3, value=testsumleft[g])

                        active_sheet.cell(column=f+g*3+2, row=3, value=testsumright[g]+testsumleft[g])

                    ff = f+g*3+2+1


                    

                    #############total###############

                    active_sheet.cell(column=ff, row=2, value="total")

                    active_sheet.cell(column=ff, row=3, value=sum(testsumright[0:testtrial]+testsumleft[0:testtrial]))

                    #############target###############

                    active_sheet.cell(column=ff+1, row=2, value="target")

                    #############preference###############

                    active_sheet.cell(column=ff+2, row=2, value="preference")

                    #############side bias#########

                    active_sheet.cell(column=ff+3, row=2, value="side bias")

                    active_sheet.cell(column=ff+3, row=3, value=sum(testsumright[0:testtrial])/sum(testsumright[0:testtrial]+testsumleft[0:testtrial]))

                    #############upper total sum#########

                    active_sheet.cell(column=ff+4, row=2, value="right total")

                    active_sheet.cell(column=ff+4, row=3, value=sum(sumright))

                    #############lower total sum#########

                    active_sheet.cell(column=ff+5, row=2, value="left total")

                    active_sheet.cell(column=ff+5, row=3, value=sum(sumleft))

                    #############total familiarization#########

                    active_sheet.cell(column=ff+6, row=2, value="total familiarization time")

                    active_sheet.cell(column=ff+6, row=3, value=sum(sumright+sumleft))

                    #############first two familiarization#########

                    active_sheet.cell(column=ff+7, row=2, value="first two")

                    active_sheet.cell(column=ff+7, row=3, value=sum(sumright[0:trial-4]+sumleft[0:trial-4]))

                    #############last two familiarization#########

                    active_sheet.cell(column=ff+8, row=2, value="last two")

                    active_sheet.cell(column=ff+8, row=3, value=sum(sumright[trial-2:trial]+sumleft[trial-2:trial]))

                    #############familiarization proportion#########

                    active_sheet.cell(column=ff+9, row=2, value="proportion of familiarization")

                    active_sheet.cell(column=ff+9, row=3, value=sum(sumright[trial-2:trial]+sumleft[trial-2:trial])/sum(sumright[0:testtrial]+sumleft[0:testtrial]))

                    #############chancel level######################

                    active_sheet.cell(column=ff+10, row=2, value="chance level")

                    active_sheet.cell(column=ff+10, row=3, value=0.5)

                    book.save(d.strftime("%Y%m%d%H%M")+ "_cal" + "_" +str(flag) +".xlsx")

                    flag += 1



                ################################

                # それぞれのキー押しについて時間を計算

                if event.key == K_LEFT:

                    start_left = time.perf_counter()

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[0,0])

                    print("押されたキー = " + pygame.key.name(event.key))

                    pygame.display.update()  

                if event.key == K_RIGHT:

                    start_right = time.perf_counter()

                    text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    screen.blit(text,[300,0])

                    print("押されたキー = " + pygame.key.name(event.key))

                    pygame.display.update()

            if event.type == KEYUP: #キーを離したとき

                if event.key == K_LEFT:

                    end_left = time.perf_counter()

                    out_left = (end_left - start_left)*1000

                    results.append([out_left,0])

                    sumout_left.append(out_left)

                    #text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    #screen.blit(text,[0,30])

                    print("離したキー = " + pygame.key.name(event.key) + ":" + str(out_left))

                    pygame.display.update()  

                if event.key == K_RIGHT:

                    end_right = time.perf_counter()

                    out_right = (end_right - start_right)*1000

                    results.append([0,out_right])

                    sumout_right.append(out_right)

                    #text = font.render(pygame.key.name(event.key), True,(255,255,255))

                    #screen.blit(text,[300,30])

                    print("離したキー = " + pygame.key.name(event.key) + ":" + str(out_right))

                    pygame.display.update()

                if event.key == K_LSHIFT and count <trial:

                    sumleft.append(sum(sumout_left))

                    sumright.append(sum(sumout_right))

                    sumout_left = []

                    sumout_right = []

                    text = font.render("Next trial", True,(255,255,255))

                    screen.blit(text,[150,0])

                    print("Next" + pygame.key.name(event.key))

                    pygame.display.update()

                    count += 1

                    print(count)

                if event.key == K_LSHIFT and count >=trial:

                    if count == trial:

                        count += 1

                        pass

                    else:

                        testsumleft.append(sum(sumout_left))

                        testsumright.append(sum(sumout_right))

                        print(testsumleft)

                        sumout_left = []

                        sumout_right = []

                        text = font.render("Next trial", True,(255,255,255))

                        screen.blit(text,[150,0])

                        print("Next" + pygame.key.name(event.key))

                        pygame.display.update()

                        print(count)

                        count += 1

             

pygame.quit()

sys.exit()

複数のデータを一気に読み込みたい。けど,それは自分で選択したい。

Pythonのglobを使用すれば一括で複数のファイルを読み込むことができます。ただ,手動で複数選択したいときもあります。そんなときはtkinterを使ってファイルを選択するダイアログを出すと便利。下記コードを実施するとファイル選択画面が出てきて,手動で選択できます。もちろん[ctrl]+[A]で全選択も可能。

import os, tkinter, tkinter.filedialog, tkinter.messagebox

#################ファイルを読み込む(複数可能)###########################

root = tkinter.Tk()

root.attributes('-topmost', True)

root.withdraw()

fTyp = [("","*")]

iDir = os.path.abspath(os.path.dirname(__file__))

# tkinter.messagebox.showinfo('分析実行','処理ファイルを選択してください!')

file = tkinter.filedialog.askopenfilenames(filetypes = fTyp,initialdir = iDir)

#list = list(file)

#tkinter.messagebox.showinfo('○×プログラム',list)

#############################################################


globで一括読み込みはこちら。

import glob

INPUT_PATH = r"" #”ここ”に読み込みたいフォルダのパスを入れる

files = glob.glob(INPUT_PATH + "*") #*でワイルドカードにしているためこのフォルダ内のすべてを読み込む。