def get_question(handler_input, first_question: bool = False, player_obj: object = None) -> str: """Returns a question for survival mode.""" if not first_question: QuestionAttr.increment_questions_answered(handler_input) ## Get new question flag_get_new_question = True while flag_get_new_question: new_question = SMQuestions.get_sampled_num(handler_input) if not GenQuestions.check_same_question(handler_input, new_question): flag_get_new_question = False ## Save question QuestionAttr.save_question(handler_input, new_question) ## Messages ms_question_intro = SMQuestions.get_ms_question_intro( handler_input, first_question=first_question, player_obj=player_obj) ms_question = GenQuestions.format_question(new_question) speech_list = (ms_question_intro, ms_question) return get_linear_nlg(speech_list)
def get_question(handler_input, first_question: bool = False) -> str: """Returns question for the user.""" attr = handler_input.attributes_manager.session_attributes if not first_question: QuestionAttr.increment_questions_answered(handler_input) sc_questions = attr['sc_questions'] question = sc_questions.pop() attr['sc_questions'] = sc_questions QuestionAttr.save_question(handler_input, question) return GenQuestions.format_question(question)
def record_wrong_question(handler_input) -> None: """Saves the question as a session attribute. Implementation NOTE: Currently using series of get statements May be able to use a while loop instead that checks if data type is dict. May also like to change to try-except statement. """ attr = handler_input.attributes_manager.session_attributes ## Keys wrong_quest_by_date = attr['wrong_quest_by_date'] today = attr['today'] table_1, table_2 = QuestionAttr.get_question_tables(handler_input, integers=False) log_all(wrong_quest_by_date, today, table_1, table_2) ## Get Dicts incorrect_today_dict = wrong_quest_by_date.get(today, {}) tbl_1_incorrect_dict = incorrect_today_dict.get(table_1, {}) tbl_2_val = tbl_1_incorrect_dict.get(table_2, 0) log_all(incorrect_today_dict, tbl_1_incorrect_dict, tbl_2_val) ## Val tbl_2_val += 1 ## Update dicts tbl_1_incorrect_dict[table_2] = tbl_2_val incorrect_today_dict[table_1] = tbl_1_incorrect_dict wrong_quest_by_date[today] = incorrect_today_dict attr['wrong_quest_by_date'] = wrong_quest_by_date log_all(incorrect_today_dict, tbl_1_incorrect_dict, tbl_2_val) return
def get_higher_table_difficulty( handler_input, player_obj: object = None, tables: tuple = None, answered_tables: list = None ) -> float: """Returns z_score for the table with the highest difficulty. Difficulty is a constructed measure dependent on greatness of tables, e.g., 6 > 5.""" if not player_obj: player_obj = PlayerDict.load_player_obj(handler_input) if tables is None: tables = QuestionAttr.get_question_tables(handler_input, integers=True) if answered_tables is None: answered_tables = player_obj.get_answered_tables(integers = True) inflated_mean_table = mean(answered_tables) + 1 higher_table = max( [int(table) for table in tables]) z_score = calc_z_score( data_point= higher_table, data_mean = inflated_mean_table, data= answered_tables, required_data_length= stats.data.SUF_ANSWERED_TABLES ) return z_score
def get_same_question(handler_input) -> str: """Returns the same question to the user.""" question = QuestionAttr.get_question_tables(handler_input, integers=False) question = GenQuestions.format_question(question) return question
def get_question( handler_input, player_object: object, practice_type: str, first_question: bool = False, ) -> str: """Asks the user a multiplication question based on custom practice type.""" attr = handler_input.attributes_manager.session_attributes if not first_question: QuestionAttr.increment_questions_answered(handler_input) flag_get_new_question = True while flag_get_new_question: new_question = CP_QuestionByType.get_question_type( handler_input, player_object, practice_type) if (not GenQuestions.check_same_question(handler_input, new_question) or practice_type == custom_practice.data.PRACT_TYPES[ 0] # can repeat on incorrect from date. ): flag_get_new_question = False ## Message Intro ms_intro = CP_Questions.get_ms_question_intro(handler_input, player_object, practice_type, first_question, new_question) ## Save Question QuestionAttr.save_question( handler_input, new_question ) # NOTE: Save question after for duplicates on incorrect-problems. ms_question = GenQuestions.format_question(new_question) ## Punct for interrogative if attr.get('interrogative_question', False): punct = '?' attr['interrogative_question'] = False else: punct = '' speech_list = (ms_intro, ' ', ms_question, punct) speech = ''.join(speech_list) return CardFuncs.format_prompt(speech)
def get_sm_pause_length(handler_input) -> str: """Returns pause for survival mode dependent on the problem difficulty.""" tables = QuestionAttr.get_question_tables(handler_input, True) harder_table = max(tables) pause_level = round(harder_table * (1 / 10) + 1, 2) pause_level = pause_level if pause_level < 3 else 3 return Pauser.get_p_level(level=pause_level)
def check_same_question(handler_input, new_question: tuple) -> bool: """Returns boolean representing if same question asked to the user.""" old_question_1, old_question_2 = QuestionAttr.get_question_tables( handler_input, integers=True) log_all(old_question_1, old_question_2, new_question[0], new_question[1]) return (new_question[0] == old_question_1 and new_question[1] == old_question_2)
def handle(self, handler_input): logger.info("HAN GetAnswerHandler") speech_list = [] ms_answer = GetAnswerSpeech.get_ms_answer(handler_input) next_question = FPQuestions.get_question(handler_input) QuestionAttr.increment_questions_answered(handler_input, False) # undo increment. ## NOTE: would not need to de-increment with better modulation. speech_list += Pauser.make_ms_pause_level_list(ms_answer, 2, next_question) reprompt = next_question speech = ' '.join(speech_list) card_title, card_text = CardFuncs.get_card_info(handler_input, speech) return (handler_input.response_builder.speak(speech).ask( reprompt).set_card(SimpleCard(card_title, card_text)).response)
def check_answer(handler_input) -> bool: """Returns boolean if user answer is correct.""" table_1, table_2 = QuestionAttr.get_question_tables(handler_input, True) answer = SlotUtils.get_slot_val_by_name(handler_input, 'answer') if not answer: logger.error("check_answer: No answer found.") ## NOTE: if this error is being thrown, need to incorporate ## FallbackUtils.return_unknown_slot_response() return False return (table_1 * table_2 == int(answer))
def calculate_excite_level(handler_input, player_obj: object = None, survival_mode: bool = False) -> int: """Returns congratulations level to return to the user. Conditions checked: - Consecutive incorrect - Consecutive correct - If user has high (f) error on table - Table difficulty vs average table difficulty """ attr = handler_input.attributes_manager.session_attributes consecutive_incorrect = attr.get('consecutive_incorrect', 0) consecutive_correct = attr.get('consecutive_correct', 0) consecutive_correct = (consecutive_correct + 1) if consecutive_correct is not None else 1 excite_level = 0 if consecutive_incorrect and (not survival_mode): return consecutive_incorrect - (1 - random.random()) elif ((consecutive_correct) % 5 == 0) and (not survival_mode): return CongratLevel.get_level_consecutive_correct( consecutive_correct) tables = QuestionAttr.get_question_tables(handler_input, integers=False) if not player_obj: player_obj = PlayerDict.load_player_obj(handler_input) ## Check table error frequency higher_f_error = UserStats.get_higher_table_error_freq( handler_input, player_obj=player_obj, tables=tables) logger.debug(f"higher_f_error {higher_f_error}") if higher_f_error >= 1.5: ## Arbitrary value. NOTE: Revist. return higher_f_error ## Check Relative Table difficulty higher_table_difficulty = UserStats.get_higher_table_difficulty( handler_input, player_obj=player_obj, tables=tables) logger.debug(f"higher_table_difficulty {higher_table_difficulty}") if higher_table_difficulty > 1.5: return higher_table_difficulty return excite_level
def remove_question_from_incorrect_questions(handler_input) -> None: """Removes the question from the incorrect questions. Also checks if dictionary is empty and deletes. """ attr = handler_input.attributes_manager.session_attributes wrong_quest_by_date = attr['wrong_quest_by_date'] date_key = CP_Utils.get_oldest_date(wrong_quest_by_date) date_dict = wrong_quest_by_date[date_key] table_1, table_2 = QuestionAttr.get_question_tables(handler_input, integers = False) log_all( date_dict, table_1, table_2) table_1_dict = date_dict[table_1] num_incorrect = table_1_dict[table_2] log_all(table_1_dict, num_incorrect) ## Reduce counts of incorrect. num_incorrect = CP_Utils.reduce_num_incorrect(num_incorrect) ## Resave dictionaries. table_1_dict[table_2] = num_incorrect date_dict[table_1] = table_1_dict wrong_quest_by_date[date_key] = date_dict log_all(table_1_dict, date_dict, wrong_quest_by_date) ## Should refactor into many different methods. logger.debug(num_incorrect) if num_incorrect == 1: # already asked, so delete & any unnecessary dicts CP_Attr.del_dict_key(table_1_dict, key = table_2) if len(table_1_dict.keys()) == 0: CP_Attr.del_dict_key(date_dict, table_1) if len(date_dict.keys()) == 0: CP_Attr.del_dict_key(wrong_quest_by_date, key = date_key) logger.debug(wrong_quest_by_date) attr['wrong_quest_by_date'] = wrong_quest_by_date return
def get_ms_answer(handler_input, include_correct_ans: bool = True) -> str: """Returns message of what the answer is. Format: Num1 * Num2 = Num3""" table_1, table_2 = QuestionAttr.get_question_tables(handler_input, integers=True) user_answer = SlotUtils.get_slot_val_by_name(handler_input, 'answer') answer = str(table_1 * table_2) + '.' ms_question = check_answer.data.MS_QUESTION.format(table_1, table_2) speech_list = [ ms_question, check_answer.data.MT_EQUALS, answer, ] if include_correct_ans: ms_ans = check_answer.data.MS_NOT_ANS.format(user_answer) speech_list.append(ms_ans) return get_linear_nlg(speech_list)
def get_higher_table_error_freq( handler_input, player_obj: object = None, tables: tuple = None ) -> float: """Returns z_score for the highest error tables.""" if not player_obj: player_obj = PlayerDict.load_player_obj(handler_input) if tables is None: tables = QuestionAttr.get_question_tables(handler_input, integers=False) times_tables_info = player_obj.get_times_table_info() times_tables_mean_err_list = [] for table in times_tables_info.keys(): table_mean = float(times_tables_info[table]['mean']) table_data = times_tables_info[table]['table_data'] if len(table_data) > stats.data.SUF_TABLE_DATA: times_tables_mean_err_list.append(1 - table_mean) # inversed, so errors are higher. ## Exit if not enough data. if len(times_tables_mean_err_list) <= stats.data.SUF_ERR_LIST: return 0 question_tables_err = [] for table in tables: table = str(table) table_info = float( times_tables_info[table]['mean']) table_info = (1 - table_info) # inverse mean. question_tables_err.append( table_info) max_table_err = max(question_tables_err) z_score = calc_z_score( data_point= max_table_err, data= times_tables_mean_err_list, ) return ( z_score)