class CognitiveExercise(object): """ Cognitive Exercises Base Class.""" def __init__(self, cog_test): """ Constructor """ self.language = cog_test.language self.audioSource = Constants.AUDIO_SOURCE self.tempDir = Constants.TEMP_DIR self.cogTest = cog_test self.recordTime = 5 self.maxReruns = 3 self.askValidation = True self.rh = RappRobot() self.ch = RappPlatformAPI() self.performance = { 'correct_answers': 0, 'wrong_answers': 0, 'final_score': 0 } self.print_info() def run(self): """ Execute this cognitive exercise application. """ try: self.rh.motion.enableMotors() self.rh.humanoid_motion.goToPosture("Sit", 0.5) self.intro() self.pronounce_questions() ex = self.score() self.rh.humanoid_motion.goToPosture("Sit", 0.5) self.rh.motion.disableMotors() except Exception as e: print e.message self.error_termination() if ex: sys.exit(0) # Process exit success status else: sys.exit(1) # Process exit error status def record_voice(self, recordTime): """ Use this method to record users speech. @type recordTime: Int @param recordTime: Duration of the recording in seconds """ taskId = self.rh.sensors.rastaLedsOn() recDest = "{0}/micrec-{1}.{2}".format( Constants.TEMP_DIR, ''.join([str(randint(0, 9)) for p in range(0, 9)]), 'wav') self.rh.audio.record(recDest, recordTime, 'wav', 16000, [0, 0, 1, 0]) self.rh.sensors.rastaLedsOff(taskId) return recDest def error_termination(self): """ Inform on termination with error.""" self.rh.audio.speak( u'Κατι πήγε λαθος στο σύστημα. Άμεσος τερματισμός!', self.language, True) sys.exit(0) def detect_words(self, language, possibAns, correctAns, waitT): """ Detect words given by possible answers and correct answer. Using the SpeechDetectionSphinx4 Platform service to perform speech detection. @param language @param possibAns @param correctAns @param waitT """ print color.cyan + '----------> Detect Words' + color.clear print "Words:" for w in possibAns: print w.encode("utf-8") print "ans: " + correctAns.encode("utf-8") print color.cyan + '<----------------------' + color.clear for i in range(0, len(possibAns)): possibAns[i] = possibAns[i].replace(" ", "-") correctAns = correctAns.replace(" ", "-") resp = self.rh.audio.speechDetection(possibAns, waitT, self.language) try: print 'Detect-Words: word: {0}, probability: {1}, error: {2}'.format( resp['word'], resp['probability'], resp['error']) except Exception as e: print e.message if resp['error'] or resp['probability'] < 0.4: # Threshold prob self.rh.audio.speak(u'Δεν άκουσα. Μιλήστε πιο δυνατά παρακαλώ', self.language, True) return 'Rerun', '<unk>' if self.askValidation: usrAns = self.ask_validation(resp['word'].decode('utf8')) if not usrAns: return 'Rerun', '<unk>' if resp['word'] == correctAns.encode('utf8'): return True, resp['word'].replace("-", " ") else: return False, resp['word'].replace("-", " ") def intro(self): """Intro to cognitive exercises.""" self.rh.audio.speak(u'Ας ξεκινήσουμε τα παιχνίδια γνώσεων', self.language, True) # TODO inform user on selected exercise class. # self.tts(u'Η κατηγορία ασκήσεων είναι... ' + ) flag = False waitOnAnswer = 3 # seconds while not flag: self.rh.audio.speak( u'Εισαι ετοιμος για να ξεκινήσουμε το παιχνίδι?', self.language, True) detected = self.detect_yes(self.language, waitOnAnswer) if detected == 'Rerun': pass elif detected: self.rh.audio.speak(u'Τέλεια! Ας ξεκινήσουμε.', self.language, True) flag = True elif not detected: self.rh.audio.speak(u'Τερματισμός ασκήσεων γνώσης.', self.language, True) sys.exit(0) else: pass def print_info(self): """Print Selected cognitive exercise general information.""" print color.ok + "\n" + \ '**************************************************' + '\n' + \ '******** [Cognitive Exercises Information] *******' + '\n' + \ '**************************************************' + '\n' + \ color.clear + color.yellow + '\n' + \ '- [Test type]: ' + color.clear + self.cogTest.testType + \ color.yellow + '\n\n' + \ '- [Test Instance]: ' + color.clear + self.cogTest.instance + \ color.yellow + '\n\n' + \ '- [Test SubType]: ' + color.clear + self.cogTest.testSubType + \ color.yellow + '\n\n' + \ '- [Questions]:' + color.clear for q in self.cogTest.questions: print ' %s] ' % (self.cogTest.questions.index(q) + 1) + \ q.encode('utf8') print color.yellow + '\n' + '- [Possible Answers]: ' + color.clear for outer in self.cogTest.possibAns: qIndex = self.cogTest.possibAns.index(outer) print ' * Question #%s: %s' % ( qIndex, self.cogTest.questions[qIndex].encode('utf8')) for a in outer: aIndex = outer.index(a) print ' %s] ' % (aIndex) + a.encode('utf-8') print color.yellow + '\n' + '- [Correct Answers]' + color.clear for ca in self.cogTest.correctAns: print ' * Question #%s: %s' % \ (self.cogTest.correctAns.index(ca), ca.encode('utf-8')) print color.ok + "\n" + \ '**************************************************' + '\n' + \ '**************************************************' + '\n' + \ color.clear def print_score_info(self): """ Print final performance results. """ print color.ok + "\n" + \ '**************************************************' + '\n' + \ '********** [Cognitive Exercises Results] *********' + '\n' + \ '**************************************************' + '\n' + \ color.clear print color.success + '[Correct Answers]: ' + color.cyan + \ str(self.performance['correct_answers']) + color.clear + '\n' print color.success + '[Wrong Answers]: ' + color.cyan + \ str(self.performance['wrong_answers']) + color.clear + '\n' print color.yellow + '[Final Score]: ' + color.cyan + \ str(self.performance['final_score']) + color.clear def score(self): """ Calculate final score, pronounce it and send to the Cloud to record user's performance under the ontology. """ numQ = len(self.cogTest.questions) self.performance['final_score'] = 100.0 * \ self.performance['correct_answers'] / numQ self.print_score_info() self.rh.audio.speak(u'Το σκορ είναι', self.language, True) msg = u'%s σωστές απαντήσεις από τις %s ερωτήσεις' % \ (self.performance['correct_answers'], numQ) self.rh.audio.speak(msg, self.language, True) time.sleep(1) # -------------------------------------------------------------------- # Call this Platform service in order to record users performance taskId = self.rh.sensors.randomEyesOn() response = self.ch.cognitiveRecordPerformance( test_instance=self.cogTest.instance, score=self.performance['final_score']) self.rh.sensors.randomEyesOff(taskId) # -------------------------------------------------------------------- if response['error']: print response['error'] msg = u'Αποτυχία εγγραφής του τελικού σκορ' self.rh.audio.speak(msg, self.language, True) return False else: msg = u'Το σκορ σας καταγράφηκε στο σύστημα' self.rh.audio.speak(msg, self.language, True) return True def detect_yes(self, language, waitT=5.0): """ Method to recognize yes/no (ναι/οχι) words.""" if language == 'el': possibAns = [u'ναι', u'οχι'] correctAns = u'ναι' elif language == 'en': possibAns = ['yes', 'no'] correctAns = 'yes' else: pass resp = self.rh.audio.speechDetection(possibAns, waitT, self.language) try: print 'Detect-Yes: word: {0}, probability: {1}, error: {2}'.format( resp['word'], resp['probability'], resp['error']) except Exception as e: print e.message if resp['error'] or resp['probability'] < 0.4: # Threshold prob self.rh.audio.speak(u'Δεν άκουσα. Μιλήστε πιο δυνατά παρακαλώ', self.language, True) return 'Rerun' elif resp['word'] == correctAns.encode('utf8'): return True else: return False def pronounce_questions(self): """ Core of the Exercise execution. - Pronounce questions. - Capture answers. - Recognise answer based on Platform's Speech-Recognition service. - Validate answer. """ waitOnAnswer = 5 # Seconds numQ = len(self.cogTest.questions) self.rh.audio.speak(u'Έχω ετοιμάσει %s ερωτήσεις' % numQ, self.language, True) time.sleep(1) self.rh.audio.speak(u'Ας ξεκινήσουμε τις ερωτήσεις', self.language, True) for i in range(0, numQ): reruns = 0 detected = 'Rerun' self.rh.audio.speak(u'Ερώτηση %s' % (i + 1), self.language, True) # time.sleep(1) self.rh.audio.speak(self.cogTest.questions[i], self.language, True) # time.sleep(1) possAns = self.cogTest.possibAns[i] correctAns = self.cogTest.correctAns[i] while detected == 'Rerun': detected, wordDetected = self.detect_words( self.language, possAns, correctAns, waitOnAnswer) if detected == 'Rerun': reruns = reruns + 1 if reruns == self.maxReruns: self.rh.audio.speak( u'{0} αποτυχημένες προσπάθειες.'.format(reruns), self.language, True) self.ask_random_ans(possAns, correctAns) break # Break while loop else: # Rerun self.rh.audio.speak( u'Επανέλαβε την απάντηση παρακαλώ.', self.language, True) elif detected: self.performance['correct_answers'] += 1 self.rh.audio.speak(u'Σωστό!', self.language, True) elif not detected: self.performance['wrong_answers'] += 1 self.rh.audio.speak(u'Λάθος απάντηση', self.language, True) else: pass def ask_random_ans(self, possAns, correctAns): randAns = possAns[randint(0, len(possAns) - 1)] isValid = True if \ randAns.encode('utf8') == correctAns.encode('utf8') else False while True: self.rh.audio.speak(u'Είναι η σωστή απάντηση ... %s ?' % randAns, self.language, True) detected = self.detect_yes(self.language, self.recordTime) if detected == 'Rerun': self.rh.audio.speak(u'Επανάληψη.', self.language, True) pass elif detected == isValid: self.performance['correct_answers'] += 1 self.rh.audio.speak(u'Σωστό!', self.language, True) return True else: self.performance['wrong_answers'] += 1 self.rh.audio.speak(u'Λάθος απάντηση', self.language, True) return False def ask_validation(self, ans): while True: self.rh.audio.speak(u'Είπατε... %s ?' % ans, self.language, True) detected = self.detect_yes(self.language, self.recordTime) if detected == 'Rerun': pass else: return detected
class CognitiveTestRecordTests(unittest.TestCase): def setUp(self): self.ch = RappPlatformAPI() def test_recordReasoning(self): response = self.ch.cognitiveExerciseSelect('ReasoningCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(instance, 50) self.assertEqual( 'CognitiveTestPerformed' in response['performance_entry'], True) def test_recordAwareness(self): response = self.ch.cognitiveExerciseSelect('AwarenessCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(instance, 50) self.assertEqual( 'CognitiveTestPerformed' in response['performance_entry'], True) def test_recordArithmetic(self): response = self.ch.cognitiveExerciseSelect('ArithmeticCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(instance, 50) self.assertEqual( 'CognitiveTestPerformed' in response['performance_entry'], True) def test_recordWrongType(self): response = self.ch.cognitiveExerciseSelect('ArithmeticCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(3, 50) self.assertNotEqual(response['error'], u'') def test_recordWrongScoreType(self): response = self.ch.cognitiveExerciseSelect('ArithmeticCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(instance, '200') self.assertNotEqual(response['error'], u'') def test_recordWrongScoreValues(self): response = self.ch.cognitiveExerciseSelect('ArithmeticCts') self.assertEqual(response['error'], u'') self.assertNotEqual(response['test_instance'], u'') instance = response['test_instance'] response = self.ch.cognitiveRecordPerformance(instance, 200) self.assertNotEqual(response['error'], u'') response = self.ch.cognitiveRecordPerformance(instance, -200) self.assertNotEqual(response['error'], u'')
class CognitiveExercise(object): """ Cognitive Exercises Base Class.""" def __init__(self, cog_test): """ Constructor """ self.language = cog_test.language self.audioSource = Constants.AUDIO_SOURCE self.tempDir = Constants.TEMP_DIR self.cogTest = cog_test self.recordTime = 5 self.maxReruns = 3 self.askValidation = True self.rh = RappRobot() self.ch = RappPlatformAPI() self.performance = { 'correct_answers': 0, 'wrong_answers': 0, 'final_score': 0 } self.print_info() def run(self): """ Execute this cognitive exercise application. """ try: self.rh.motion.enableMotors() self.rh.humanoid_motion.goToPosture("Sit", 0.5) self.intro() self.pronounce_questions() ex = self.score() self.rh.humanoid_motion.goToPosture("Sit", 0.5) self.rh.motion.disableMotors() except Exception as e: print e.message self.error_termination() if ex: sys.exit(0) # Process exit success status else: sys.exit(1) # Process exit error status def record_voice(self, recordTime): """ Use this method to record users speech. @type recordTime: Int @param recordTime: Duration of the recording in seconds """ taskId = self.rh.sensors.rastaLedsOn() recDest = "{0}/micrec-{1}.{2}".format(Constants.TEMP_DIR, ''.join([str(randint(0, 9)) for p in range(0, 9)]), 'wav') self.rh.audio.record(recDest, recordTime, 'wav', 16000, [0, 0, 1, 0]) self.rh.sensors.rastaLedsOff(taskId) return recDest def error_termination(self): """ Inform on termination with error.""" self.rh.audio.speak(u'Κατι πήγε λαθος στο σύστημα. Άμεσος τερματισμός!', self.language, True) sys.exit(0) def detect_words(self, language, possibAns, correctAns, waitT): """ Detect words given by possible answers and correct answer. Using the SpeechDetectionSphinx4 Platform service to perform speech detection. @param language @param possibAns @param correctAns @param waitT """ print color.cyan + '----------> Detect Words' + color.clear print "Words:" for w in possibAns: print w.encode("utf-8") print "ans: " + correctAns.encode("utf-8") print color.cyan + '<----------------------' + color.clear for i in range(0, len(possibAns)): possibAns[i] = possibAns[i].replace(" ", "-") correctAns = correctAns.replace(" ", "-") resp = self.rh.audio.speechDetection(possibAns, waitT, self.language) try: print 'Detect-Words: word: {0}, probability: {1}, error: {2}'.format( resp['word'], resp['probability'], resp['error']) except Exception as e: print e.message if resp['error'] or resp['probability'] < 0.4: # Threshold prob self.rh.audio.speak(u'Δεν άκουσα. Μιλήστε πιο δυνατά παρακαλώ', self.language, True) return 'Rerun', '<unk>' if self.askValidation: usrAns = self.ask_validation(resp['word'].decode('utf8')) if not usrAns: return 'Rerun', '<unk>' if resp['word'] == correctAns.encode('utf8'): return True, resp['word'].replace("-", " ") else: return False, resp['word'].replace("-", " ") def intro(self): """Intro to cognitive exercises.""" self.rh.audio.speak(u'Ας ξεκινήσουμε τα παιχνίδια γνώσεων', self.language, True) # TODO inform user on selected exercise class. # self.tts(u'Η κατηγορία ασκήσεων είναι... ' + ) flag = False waitOnAnswer = 3 # seconds while not flag: self.rh.audio.speak(u'Εισαι ετοιμος για να ξεκινήσουμε το παιχνίδι?', self.language, True) detected = self.detect_yes(self.language, waitOnAnswer) if detected == 'Rerun': pass elif detected: self.rh.audio.speak(u'Τέλεια! Ας ξεκινήσουμε.', self.language, True) flag = True elif not detected: self.rh.audio.speak(u'Τερματισμός ασκήσεων γνώσης.', self.language, True) sys.exit(0) else: pass def print_info(self): """Print Selected cognitive exercise general information.""" print color.ok + "\n" + \ '**************************************************' + '\n' + \ '******** [Cognitive Exercises Information] *******' + '\n' + \ '**************************************************' + '\n' + \ color.clear + color.yellow + '\n' + \ '- [Test type]: ' + color.clear + self.cogTest.testType + \ color.yellow + '\n\n' + \ '- [Test Instance]: ' + color.clear + self.cogTest.instance + \ color.yellow + '\n\n' + \ '- [Test SubType]: ' + color.clear + self.cogTest.testSubType + \ color.yellow + '\n\n' + \ '- [Questions]:' + color.clear for q in self.cogTest.questions: print ' %s] ' % (self.cogTest.questions.index(q) + 1) + \ q.encode('utf8') print color.yellow + '\n' + '- [Possible Answers]: ' + color.clear for outer in self.cogTest.possibAns: qIndex = self.cogTest.possibAns.index(outer) print ' * Question #%s: %s' % ( qIndex, self.cogTest.questions[qIndex].encode('utf8')) for a in outer: aIndex = outer.index(a) print ' %s] ' % (aIndex) + a.encode('utf-8') print color.yellow + '\n' + '- [Correct Answers]' + color.clear for ca in self.cogTest.correctAns: print ' * Question #%s: %s' % \ (self.cogTest.correctAns.index(ca), ca.encode('utf-8')) print color.ok + "\n" + \ '**************************************************' + '\n' + \ '**************************************************' + '\n' + \ color.clear def print_score_info(self): """ Print final performance results. """ print color.ok + "\n" + \ '**************************************************' + '\n' + \ '********** [Cognitive Exercises Results] *********' + '\n' + \ '**************************************************' + '\n' + \ color.clear print color.success + '[Correct Answers]: ' + color.cyan + \ str(self.performance['correct_answers']) + color.clear + '\n' print color.success + '[Wrong Answers]: ' + color.cyan + \ str(self.performance['wrong_answers']) + color.clear + '\n' print color.yellow + '[Final Score]: ' + color.cyan + \ str(self.performance['final_score']) + color.clear def score(self): """ Calculate final score, pronounce it and send to the Cloud to record user's performance under the ontology. """ numQ = len(self.cogTest.questions) self.performance['final_score'] = 100.0 * \ self.performance['correct_answers'] / numQ self.print_score_info() self.rh.audio.speak(u'Το σκορ είναι', self.language, True) msg = u'%s σωστές απαντήσεις από τις %s ερωτήσεις' % \ (self.performance['correct_answers'], numQ) self.rh.audio.speak(msg, self.language, True) time.sleep(1) # -------------------------------------------------------------------- # Call this Platform service in order to record users performance taskId = self.rh.sensors.randomEyesOn() response = self.ch.cognitiveRecordPerformance( test_instance=self.cogTest.instance, score=self.performance['final_score']) self.rh.sensors.randomEyesOff(taskId) # -------------------------------------------------------------------- if response['error']: print response['error'] msg = u'Αποτυχία εγγραφής του τελικού σκορ' self.rh.audio.speak(msg, self.language, True) return False else: msg = u'Το σκορ σας καταγράφηκε στο σύστημα' self.rh.audio.speak(msg, self.language, True) return True def detect_yes(self, language, waitT=5.0): """ Method to recognize yes/no (ναι/οχι) words.""" if language == 'el': possibAns = [u'ναι', u'οχι'] correctAns = u'ναι' elif language == 'en': possibAns = ['yes', 'no'] correctAns = 'yes' else: pass resp = self.rh.audio.speechDetection(possibAns, waitT, self.language) try: print 'Detect-Yes: word: {0}, probability: {1}, error: {2}'.format( resp['word'], resp['probability'], resp['error']) except Exception as e: print e.message if resp['error'] or resp['probability'] < 0.4: # Threshold prob self.rh.audio.speak(u'Δεν άκουσα. Μιλήστε πιο δυνατά παρακαλώ', self.language, True) return 'Rerun' elif resp['word'] == correctAns.encode('utf8'): return True else: return False def pronounce_questions(self): """ Core of the Exercise execution. - Pronounce questions. - Capture answers. - Recognise answer based on Platform's Speech-Recognition service. - Validate answer. """ waitOnAnswer = 5 # Seconds numQ = len(self.cogTest.questions) self.rh.audio.speak(u'Έχω ετοιμάσει %s ερωτήσεις' % numQ, self.language, True) time.sleep(1) self.rh.audio.speak(u'Ας ξεκινήσουμε τις ερωτήσεις', self.language, True) for i in range(0, numQ): reruns = 0 detected = 'Rerun' self.rh.audio.speak(u'Ερώτηση %s' % (i+1), self.language, True) # time.sleep(1) self.rh.audio.speak(self.cogTest.questions[i], self.language, True) # time.sleep(1) possAns = self.cogTest.possibAns[i] correctAns = self.cogTest.correctAns[i] while detected == 'Rerun': detected, wordDetected = self.detect_words(self.language, possAns, correctAns, waitOnAnswer) if detected == 'Rerun': reruns = reruns + 1 if reruns == self.maxReruns: self.rh.audio.speak( u'{0} αποτυχημένες προσπάθειες.'.format(reruns), self.language, True) self.ask_random_ans(possAns, correctAns) break # Break while loop else: # Rerun self.rh.audio.speak( u'Επανέλαβε την απάντηση παρακαλώ.', self.language, True) elif detected: self.performance['correct_answers'] += 1 self.rh.audio.speak(u'Σωστό!', self.language, True) elif not detected: self.performance['wrong_answers'] += 1 self.rh.audio.speak(u'Λάθος απάντηση', self.language, True) else: pass def ask_random_ans(self, possAns, correctAns): randAns = possAns[randint(0, len(possAns) - 1)] isValid = True if \ randAns.encode('utf8') == correctAns.encode('utf8') else False while True: self.rh.audio.speak(u'Είναι η σωστή απάντηση ... %s ?' % randAns, self.language, True) detected = self.detect_yes(self.language, self.recordTime) if detected == 'Rerun': self.rh.audio.speak(u'Επανάληψη.', self.language, True) pass elif detected == isValid: self.performance['correct_answers'] += 1 self.rh.audio.speak(u'Σωστό!', self.language, True) return True else: self.performance['wrong_answers'] += 1 self.rh.audio.speak(u'Λάθος απάντηση', self.language, True) return False def ask_validation(self, ans): while True: self.rh.audio.speak(u'Είπατε... %s ?' % ans, self.language, True) detected = self.detect_yes(self.language, self.recordTime) if detected == 'Rerun': pass else: return detected