Как заставить программу работать при вызове функции вместо использования массива numpy? - PullRequest
0 голосов
/ 07 февраля 2019

Это код теста NBack .Когда я выполняю код как есть, он работает.Последовательность, которая появляется на экране:

self.sequence = np.array([0,0,0,1,1,1,6,6,6,0,1,2,3,4,5,6,7,8,0,1])

Но у меня есть функция, которая генерирует последовательности, которые я хочу использовать вместо этого массива.Это ZBack.py Когда я вызываю мой ZBack.py self.sequence = generateZBackSequence(20, 5) вместо массива, программа не работает.Он выводит эту ошибку:

Exception in thread Thread-14:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 917, in _bootstrap_inner
self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 865, in run
self._target(*self._args, **self._kwargs)
  File "C:/Users/Python_Scripts/N-back.py", line 198, in targetTask
for i in range(self.sequence.shape[0]):
AttributeError: 'NBack' object has no attribute 'sequence'

Что я делаю не так?Почему он говорит мне, что атрибут 'sequence' не существует?Я уже проверил отступ.Мой ZBack.py тоже возвращает массив.

import tkinter as tk
from tkinter import Tk
from threading import Thread
from keylogger.KeyLogger import KeyLogger
from time import sleep
from nBackTools.NBackTools import *
from nBackTools.ZBack import *

from random import randint
import numpy as np

import csv


def _create_circle(self, x, y, r, **kwargs):
    return self.create_oval(x-r, y-r, x+r, y+r, **kwargs)
tk.Canvas.create_circle = _create_circle


class NBack:

    def __init__(self, master):

        ##Title of the window
        self.master = master
        master.title("N-Back")

        ##It measures the screen size (width x height + x + y)
        ##The opened window will be based on the screen size
        master.geometry("{0}x{1}-0+0".format(master.winfo_screenwidth(), master.winfo_screenheight()))
        self.canvas = tk.Canvas(master, width=master.winfo_screenwidth(), height=master.winfo_screenheight(), \
                            borderwidth=0, highlightthickness=0, bg="grey")


        self.canvasWidth = master.winfo_screenwidth()
        self.canvasHeight =  master.winfo_screenheight()

        self.createLines()
        self.createText()

        self.canvas.grid()


        self.t = Thread(target=self.targetTask,)
        self.t.daemon = True
        self.t.start()


        ## Positions of the circles ("stims")

        ##          -   -                      
        ##        0 - 1 - 2                     
        ##      ------------                   
        ##       3  - 4 - 5                      
        ##      ------------                   
        ##       6  - 7 - 8                      
        ##          -   -                        

        self.positions = np.array([[(self.canvasWidth/2)-130, (self.canvasHeight/2)-130],\
                               [(self.canvasWidth/2), (self.canvasHeight/2)-130],\
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)-130],\
                              [(self.canvasWidth/2)-130, (self.canvasHeight/2)],\
                               [(self.canvasWidth/2), (self.canvasHeight/2)],\
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)],\
                              [(self.canvasWidth/2)-130, (self.canvasHeight/2)+130], \
                               [(self.canvasWidth/2), (self.canvasHeight/2)+130], \
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)+130]])


        ###############################################
        ###############################################
        #THIS IS THE PROBLEM!!!

        #self.sequence = generateZBackSequence(20, 5)
        self.sequence = np.array([0,0,0,1,1,1,6,6,6,0,1,2,3,4,5,6,7,8,0,1])

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

"""

ADDING LINES TO THE SCREEN

"""


    def createLines(self, linewidth = 5):
        #Vertical 1
        self.canvas.create_line((self.canvasWidth/2)-65, (self.canvasHeight/2)-65-130, \
                            (self.canvasWidth/2)-65, (self.canvasHeight/2)+65+130, width= linewidth )
        #Vertical 2
        self.canvas.create_line((self.canvasWidth/2)+65, (self.canvasHeight/2)-65-130, \
                            (self.canvasWidth/2)+65, (self.canvasHeight/2)+65+130, width= linewidth )
        #Horizontal1
        self.canvas.create_line((self.canvasWidth/2)-65-130, (self.canvasHeight/2)-65, \
                            (self.canvasWidth/2)+65+130, (self.canvasHeight/2)-65, width= linewidth )
        #Horizontal2
        self.canvas.create_line((self.canvasWidth/2)-65-130, (self.canvasHeight/2)+65, \
                            (self.canvasWidth/2)+65+130, (self.canvasHeight/2)+65, width= linewidth )


"""

ADDING TEXT TO THE SCREEN

"""


    def createText(self):
        self.canvas.create_text((self.canvasWidth/4), (self.canvasHeight - self.canvasHeight/4), text="A=YES", font=( None, 20))
        self.canvas.create_text((self.canvasWidth/4), (self.canvasHeight - self.canvasHeight/4)+50, text="S=NO", font=( None, 20))



"""

CIRCLES APPEAR AND DISAPPEAR

"""


    def targetTask(self):
        thisnb = randint(75,900*2)

        targetFile = open(str(thisnb)+"_targets.csv",'w', newline='')
        writer = csv.writer(targetFile)

        ##Loops from 0 to the Number of circles that will appear (default=20)
        for i in range(self.sequence.shape[0]):
            posX = self.positions[self.sequence[i]][0]
            posY = self.positions[self.sequence[i]][1]

            print(": (%d,%d)" % (posX,posY))
            ##Records the coordenates in an excel file
            writer.writerow([posX,posY])

            ## How many seconds each circle will appear
            circle = self.canvas.create_circle(posX, posY, 55, fill="black", outline="#000", width=1)
            sleep(1)

            ## Delete circle
            ## How many seconds circle dissapears
            self.canvas.delete(circle)
            sleep(2)


        sleep(1)
        print('All done')
        targetFile.close()
        self.master.destroy()

root = Tk()
my_gui = NBack(root)
root.mainloop()

Это ZBack.py:

import numpy as np
import random

def generateZBackSequence(nbTrial, nbOfYes):
    ##all possible positions of the "stims"
    allStims = [0,1,2,3,4,5,6,7,8]

    ##sequence is an array of -1s and has the size of nbTrial (default=20)
    sequence = np.zeros((nbTrial,))-1

    ##security: in case the required "yeses" are too many
    if nbOfYes > nbTrial:
        print('generateZBackSequence: invalid nb of Yeses')
        return None

    ##Pick randomly 1 stim and repeat it (default=5)
    yeses = np.repeat(random.sample(allStims, 1),nbOfYes)
    print("yeses:", yeses, '\n')

    ##Making the first value in the sequence = value in yeses
    sequence[0]=yeses[0]
    #print("sequence:", sequence, '\n')

    ##Contains the "stims" that were not randomly sampled
    newStims = [x for x in allStims if x not in yeses]
    #print("newStims:", newStims, '\n')


    """

    STEP 1 - impose the yeses

    """


    ##nbOfYes-1, because there is already a "yeses" in sequence[0]
    for i in range(nbOfYes-1):
        idxValid = False

        while idxValid==False:
            ##select index randomly, from 1 to 19
            idx = random.randint(1, nbTrial-1)

            if sequence[idx]==-1:
                idxValid = True
        print("idx:", idx, '\n')

        ##insert yeses in the random index
        sequence[idx] = yeses[i]
        #print("sequence_idx:", sequence)


    """

    STEP 2 - fill in the sequence

    """


    ##Makes a "for" from 0 to 19
    for i in range(sequence.shape[0]):
        if sequence[i]==-1:
            stimValid = False

            ##Search for -1s
            while stimValid==False:
                ##Takes a random sample "stim" which is different from 'yeses'
                stimID = random.sample(newStims, 1)
                ##stimID is a list of 1 element, sequence is an array of 20 elements
                sequence[i]=stimID[0]
                stimValid = True

            else:
                stimValid = True


    return sequence


def _test():
    print(generateZBackSequence(20,5))
    print("")
    print(np.arange(0,20,1))
    pass

if __name__ == "__main__":
    _test()

1 Ответ

0 голосов
/ 08 февраля 2019

Кажется, вы вызываете метод targetTask() в конструкторе NBack в строках ниже

self.t = Thread(target=self.targetTask,)
self.t.daemon = True
self.t.start()

, прежде чем он сможет определить атрибут sequence.

Это будет исправлено путем определения sequence и всего, что вам нужно, прежде чем вы вызовете targetTask().

Конструктор будет выглядеть так:

    def __init__(self, master):

        ##Title of the window
        self.master = master
        master.title("N-Back")

        ##It measures the screen size (width x height + x + y)
        ##The opened window will be based on the screen size
        master.geometry("{0}x{1}-0+0".format(master.winfo_screenwidth(), master.winfo_screenheight()))
        self.canvas = tk.Canvas(master, width=master.winfo_screenwidth(), height=master.winfo_screenheight(), \
                            borderwidth=0, highlightthickness=0, bg="grey")


        self.canvasWidth = master.winfo_screenwidth()
        self.canvasHeight =  master.winfo_screenheight()

        self.createLines()
        self.createText()

        self.canvas.grid()

        # Notice we define self.sequence before calling self.targetTask
        self.sequence = generateZBackSequence(20, 5)


        ## Positions of the circles ("stims")

        ##          -   -                      
        ##        0 - 1 - 2                     
        ##      ------------                   
        ##       3  - 4 - 5                      
        ##      ------------                   
        ##       6  - 7 - 8                      
        ##          -   -                        

        self.positions = np.array([[(self.canvasWidth/2)-130, (self.canvasHeight/2)-130],\
                               [(self.canvasWidth/2), (self.canvasHeight/2)-130],\
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)-130],\
                              [(self.canvasWidth/2)-130, (self.canvasHeight/2)],\
                               [(self.canvasWidth/2), (self.canvasHeight/2)],\
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)],\
                              [(self.canvasWidth/2)-130, (self.canvasHeight/2)+130], \
                               [(self.canvasWidth/2), (self.canvasHeight/2)+130], \
                               [(self.canvasWidth/2)+130, (self.canvasHeight/2)+130]])


        self.t = Thread(target=self.targetTask,)
        self.t.daemon = True
        self.t.start()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...