class Session(object): '''Initializes the session and calls helper classes Subclasses: soundlib: object that handles sound playback gui: object that handles the view data: object that collects and stores data Attributes: iterations: Tracks the number of trials the participant has completed currentSound: filename of the sound that is currently playing repetitions: The number of trials the participant must complete sequenceType: Specifies sequence type (IN-ORDER, LOADED, or RANDOM) ''' def __init__(self): '''Initializes classes and begins main loop''' options = self.loadConfig() self.soundlib = SoundLibrary() self.iterations = 0 self.currentSound = "" self.repetitions = options['numRepetitions'] self.sequenceType = options['sequenceType'].upper() self.sequenceName = options['sequenceName'] self.startTime = None self.endTime = None self.gui = GUI(None) def loadConfig(self): '''Loads CONFIG.yml and prepares the parameters for the session''' dir_path = os.path.dirname(os.path.realpath(__file__)) with open(dir_path + "/../CONFIG.yml", 'r') as config: options = yaml.load(config) return options def start(self): self.gui.focus_set() dir_path = os.path.dirname(os.path.realpath(__file__)) self.gui.iconbitmap(default=dir_path + "/blank.ico") self.promptSession() self.gui.createPrompt(self.startSession, self.endSession) # Sets up the view self.gui.mainloop() def promptSession(self): ''' Prompts the experimenter for the Subject ID, Session ID, and the number of repetitions ''' while (True): self.setRepetitions() self.specifySequence() participantId = askstring(' ','Please enter Subject ID:') if participantId == None: sys.exit() sessionId = askstring(' ','Please enter Session ID:') if sessionId == None: sys.exit() sequence = self.sequenceName if self.sequenceType == 'LOADED' else self.sequenceType answer = askquestion(' ','Subject: ' + participantId + ', Session: ' + sessionId + ', Repetitions: ' + str(self.repetitions) + ', Sequence: ' + sequence + '\n\nIs this correct? ' + '\n\n(reference CONFIG.yml file for options)') if answer == "yes": break self.data = Data(participantId, sessionId) # Data collection object def setRepetitions(self): '''Prompts the user for a specific number of repetitions if none was specified''' while self.repetitions == None or self.repetitions < 1: self.repetitions = askinteger(' ','Invalid repetitions specified in CONFIG.yml.' ' Please enter the number of repetitions:') if self.repetitions == None: sys.exit() elif self.repetitions < 1: showwarning(' ','Integer must have a non-negative ' 'non-zero value.') def specifySequence(self): '''Prompts the user for a sequence type if none was specified''' if self.sequenceType == None or self.sequenceType == "LOADED" and self.sequenceName == None: self.sequenceName = "None" inorder = askquestion(' ', 'No sequence specified in CONFIG.yml.' ' Should the sounds be played in-order?') if inorder == "yes": self.sequenceType = "IN-ORDER" else: while (True): loadseq = askquestion(' ', 'Then should a sequence be loaded?') if loadseq == "yes": self.sequenceName = askstring(' ','Please specify the filename' ' containing the sequence.') seqname = self.soundlib.loadSequence(self.sequenceName) if len(self.soundlib.sequence) > 0: self.sequenceType = "LOADED" break elif loadseq == "no": self.sequenceType = "RANDOM" break def startSession(self, event): '''Prompts the user for input, loops a sound and then waits for a response. ''' self.startTime = time.time() self.gui.createEntryBox() self.gui.setLabel("\n\n\n\n\n\n\n\nPlease type what word(s) you hear " "and press ENTER to continue.", self.advanceSession) self.gui.greyScreen() self.setCurrentSound() def advanceSession(self, event): '''Adds response to the database, then clears the session''' self.endTime = time.time() self.data.add(self.currentSound, self.gui.entry.get(), self.endTime - self.startTime, self.soundlib.getCurrentSoundLength()) self.gui.entry.delete(0, END) # Clears the response form self.iterate() def iterate(self): '''Stops the sound, greys the screen, and checks if the session is over. ''' self.soundlib.stopAllSounds() self.gui.greyScreen() self.iterations += 1 if self.iterations == self.repetitions: self.gui.setLabel("\n\n\n\n\n\n\n\nThank you for participating!" "\nPlease inform the researcher that you are" " finished.", self.endSession) self.gui.entry.destroy() else: self.setCurrentSound() self.startTime = time.time() def endSession(self, event): '''Ends the session and records the data''' answer = askquestion(' ','End session?') if answer == "yes": if self.iterations > 0: self.data.recordData() sys.exit() def setCurrentSound(self): '''Sets the next sound based on the sequence type''' if (self.sequenceType == "LOADED"): self.currentSound = self.soundlib.playSequence(self.iterations) elif (self.sequenceType == "IN-ORDER" or self.sequenceType == "IN ORDER"): self.currentSound = self.soundlib.playInOrder(self.iterations) else: # Treat the sequenceType as random self.currentSound = self.soundlib.playRandom()