Пример #1
0
    def test_record_many_answers(self):
        state_answers = stats_services.get_state_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertIsNone(state_answers)

        submitted_answer_list = [
            stats_domain.SubmittedAnswer('answer a', 'TextInput', 0, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 10.0),
            stats_domain.SubmittedAnswer('answer ccc', 'TextInput', 1, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 3.0),
            stats_domain.SubmittedAnswer('answer bbbbb', 'TextInput', 1, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 7.5),
        ]
        stats_services.record_answers(self.EXP_ID, self.exploration.version,
                                      self.exploration.init_state_name,
                                      'TextInput', submitted_answer_list)

        # The order of the answers returned depends on the size of the answers.
        state_answers = stats_services.get_state_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(state_answers.exploration_id, 'exp_id0')
        self.assertEqual(state_answers.exploration_version, 1)
        self.assertEqual(state_answers.state_name,
                         feconf.DEFAULT_INIT_STATE_NAME)
        self.assertEqual(state_answers.interaction_id, 'TextInput')
        self.assertEqual(state_answers.get_submitted_answer_dict_list(),
                         [{
                             'answer': 'answer a',
                             'time_spent_in_sec': 10.0,
                             'answer_group_index': 0,
                             'rule_spec_index': 1,
                             'classification_categorization': 'explicit',
                             'session_id': 'session_id_v',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }, {
                             'answer': 'answer ccc',
                             'time_spent_in_sec': 3.0,
                             'answer_group_index': 1,
                             'rule_spec_index': 1,
                             'classification_categorization': 'explicit',
                             'session_id': 'session_id_v',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }, {
                             'answer': 'answer bbbbb',
                             'time_spent_in_sec': 7.5,
                             'answer_group_index': 1,
                             'rule_spec_index': 0,
                             'classification_categorization': 'explicit',
                             'session_id': 'session_id_v',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }])
Пример #2
0
    def test_record_and_retrieve_single_answer_with_preexisting_entry(self):
        stats_services.record_answer(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name, 'TextInput',
            stats_domain.SubmittedAnswer('first answer', 'TextInput', 0, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'a_session_id_val', 1.0))

        state_answers = stats_services.get_state_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(state_answers.get_submitted_answer_dict_list(),
                         [{
                             'answer': 'first answer',
                             'time_spent_in_sec': 1.0,
                             'answer_group_index': 0,
                             'rule_spec_index': 0,
                             'classification_categorization': 'explicit',
                             'session_id': 'a_session_id_val',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }])

        stats_services.record_answer(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name, 'TextInput',
            stats_domain.SubmittedAnswer('some text', 'TextInput', 0, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'a_session_id_val', 10.0))

        state_answers = stats_services.get_state_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(state_answers.exploration_id, 'exp_id0')
        self.assertEqual(state_answers.exploration_version, 1)
        self.assertEqual(state_answers.state_name,
                         feconf.DEFAULT_INIT_STATE_NAME)
        self.assertEqual(state_answers.interaction_id, 'TextInput')
        self.assertEqual(state_answers.get_submitted_answer_dict_list(),
                         [{
                             'answer': 'first answer',
                             'time_spent_in_sec': 1.0,
                             'answer_group_index': 0,
                             'rule_spec_index': 0,
                             'classification_categorization': 'explicit',
                             'session_id': 'a_session_id_val',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }, {
                             'answer': 'some text',
                             'time_spent_in_sec': 10.0,
                             'answer_group_index': 0,
                             'rule_spec_index': 1,
                             'classification_categorization': 'explicit',
                             'session_id': 'a_session_id_val',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }])
Пример #3
0
    def test_record_answers_exceeding_one_shard(self):
        # Use a smaller max answer list size so less answers are needed to
        # exceed a shard.
        with self.swap(stats_models.StateAnswersModel,
                       '_MAX_ANSWER_LIST_BYTE_SIZE', 100000):
            state_answers = stats_services.get_state_answers(
                self.EXP_ID, self.exploration.version,
                self.exploration.init_state_name)
            self.assertIsNone(state_answers)

            submitted_answer_list = [
                stats_domain.SubmittedAnswer(
                    'answer a', 'TextInput', 0, 1,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    10.0),
                stats_domain.SubmittedAnswer(
                    'answer ccc', 'TextInput', 1, 1,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    3.0),
                stats_domain.SubmittedAnswer(
                    'answer bbbbb', 'TextInput', 1, 0,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    7.5),
            ]
            stats_services.record_answers(self.EXP_ID,
                                          self.exploration.version,
                                          self.exploration.init_state_name,
                                          'TextInput',
                                          submitted_answer_list * 200)

            # Verify more than 1 shard was stored. The index shard (shard_id 0)
            # is not included in the shard count.
            model = stats_models.StateAnswersModel.get(
                '%s:%s:%s:%s' %
                (self.exploration.id, str(self.exploration.version),
                 self.exploration.init_state_name, '0'))
            self.assertEqual(model.shard_count, 1)

            # The order of the answers returned depends on the size of the
            # answers.
            state_answers = stats_services.get_state_answers(
                self.EXP_ID, self.exploration.version,
                self.exploration.init_state_name)
            self.assertEqual(state_answers.exploration_id, 'exp_id0')
            self.assertEqual(state_answers.exploration_version, 1)
            self.assertEqual(state_answers.state_name,
                             feconf.DEFAULT_INIT_STATE_NAME)
            self.assertEqual(state_answers.interaction_id, 'TextInput')
            self.assertEqual(
                len(state_answers.get_submitted_answer_dict_list()), 600)
Пример #4
0
 def test_can_be_converted_to_full_dict(self):
     submitted_answer = stats_domain.SubmittedAnswer(
         'Text',
         'TextInput',
         0,
         1,
         exp_domain.EXPLICIT_CLASSIFICATION, {},
         'sess',
         10.5,
         rule_spec_str='rule spec str',
         answer_str='answer str')
     self.assertEqual(
         submitted_answer.to_dict(), {
             'answer': 'Text',
             'interaction_id': 'TextInput',
             'answer_group_index': 0,
             'rule_spec_index': 1,
             'classification_categorization':
             exp_domain.EXPLICIT_CLASSIFICATION,
             'params': {},
             'session_id': 'sess',
             'time_spent_in_sec': 10.5,
             'rule_spec_str': 'rule spec str',
             'answer_str': 'answer str'
         })
Пример #5
0
    def setUp(self):
        super(SubmittedAnswerValidationTests, self).setUp()
        self.submitted_answer = stats_domain.SubmittedAnswer(
            'Text', 'TextInput', 0, 0, exp_domain.EXPLICIT_CLASSIFICATION, {},
            'session_id', 0.)

        # The canonical object should have no validation problems.
        self.submitted_answer.validate()
Пример #6
0
    def test_all_answers_returned_if_main_shard_has_few_answers(self):
        submitted_answer_list = [
            stats_domain.SubmittedAnswer('answer a', 'TextInput', 0, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 10.0),
            stats_domain.SubmittedAnswer('answer bbbbb', 'TextInput', 1, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 7.5),
        ]
        # Record 2 answers.
        stats_services.record_answers(self.EXP_ID, self.exploration.version,
                                      self.exploration.init_state_name,
                                      'TextInput', submitted_answer_list)

        sample_answers = stats_services.get_sample_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(sample_answers, ['answer a', 'answer bbbbb'])
Пример #7
0
    def test_that_state_answers_sharded_models_accumulate_stats(self):
        with self.swap(stats_models.StateAnswersModel,
                       '_MAX_ANSWER_LIST_BYTE_SIZE', 100000):

            submitted_answer_list = [
                stats_domain.SubmittedAnswer(
                    'answer a', 'TextInput', 0, 1,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    10.0),
                stats_domain.SubmittedAnswer(
                    'answer ccc', 'TextInput', 1, 1,
                    exp_domain.DEFAULT_OUTCOME_CLASSIFICATION, {},
                    'session_id_v', 3.0),
                stats_domain.SubmittedAnswer(
                    'answer bbbbb', 'TextInput', 1, 0,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    7.5),
            ]
            stats_services.record_answers(self.exp_id,
                                          self.exploration.version, 'Home',
                                          'TextInput',
                                          submitted_answer_list * 200)

        job_id = stats_jobs_one_off.GenerateV1StatisticsJob.create_new()
        stats_jobs_one_off.GenerateV1StatisticsJob.enqueue(job_id)

        self.assertEqual(
            self.count_jobs_in_taskqueue(
                taskqueue_services.QUEUE_NAME_ONE_OFF_JOBS), 1)
        self.process_and_flush_pending_tasks()

        exploration_stats = stats_services.get_exploration_stats_by_id(
            self.exp_id, self.exploration.version)

        # There are an additional two answers from the setup function.
        self.assertEqual(
            exploration_stats.state_stats_mapping['Home'].
            total_answers_count_v1, 602)

        # There is an additional answer from the setup function.
        self.assertEqual(
            exploration_stats.state_stats_mapping['Home'].
            useful_feedback_count_v1, 401)
Пример #8
0
 def _record_answer(
         self,
         answer_str,
         exploration,
         state_name,
         classification=exp_domain.DEFAULT_OUTCOME_CLASSIFICATION):
     stats_services.record_answer(
         exploration.id, exploration.version, state_name, 'TextInput',
         stats_domain.SubmittedAnswer(answer_str, 'TextInput', 0, 0,
                                      classification, {}, 'session',
                                      self.DEFAULT_TIME_SPENT))
Пример #9
0
    def test_at_most_100_answers_returned_even_if_there_are_lots(self):
        submitted_answer_list = [
            stats_domain.SubmittedAnswer('answer a', 'TextInput', 0, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 10.0),
            stats_domain.SubmittedAnswer('answer ccc', 'TextInput', 1, 1,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 3.0),
            stats_domain.SubmittedAnswer('answer bbbbb', 'TextInput', 1, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'session_id_v', 7.5),
        ]
        # Record 600 answers.
        stats_services.record_answers(self.EXP_ID, self.exploration.version,
                                      self.exploration.init_state_name,
                                      'TextInput', submitted_answer_list * 200)

        sample_answers = stats_services.get_sample_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(len(sample_answers), 100)
Пример #10
0
    def setUp(self):
        """Complete the signup process for self.ADMIN_EMAIL."""
        super(DataExtractionQueryHandlerTests, self).setUp()
        self.signup(self.ADMIN_EMAIL, self.ADMIN_USERNAME)
        self.signup(self.EDITOR_EMAIL, self.EDITOR_USERNAME)
        self.editor_id = self.get_user_id_from_email(self.EDITOR_EMAIL)
        self.exploration = self.save_new_valid_exploration(
            self.EXP_ID, self.editor_id, end_state_name='End')

        stats_services.record_answer(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name, 'TextInput',
            stats_domain.SubmittedAnswer('first answer', 'TextInput', 0, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'a_session_id_val', 1.0))

        stats_services.record_answer(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name, 'TextInput',
            stats_domain.SubmittedAnswer('second answer', 'TextInput', 0, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'a_session_id_val', 1.0))
Пример #11
0
 def _handle_event(cls, exploration_id, exploration_version, state_name,
                   interaction_id, answer_group_index, rule_spec_index,
                   classification_categorization, session_id,
                   time_spent_in_secs, params, normalized_answer):
     """Records an event when an answer triggers a rule. The answer recorded
     here is a Python-representation of the actual answer submitted by the
     user.
     """
     # TODO(sll): Escape these args?
     stats_services.record_answer(
         exploration_id, exploration_version, state_name, interaction_id,
         stats_domain.SubmittedAnswer(normalized_answer, interaction_id,
                                      answer_group_index, rule_spec_index,
                                      classification_categorization, params,
                                      session_id, time_spent_in_secs))
Пример #12
0
 def test_dict_may_not_include_rule_spec_str_or_answer_str(self):
     submitted_answer = stats_domain.SubmittedAnswer(
         'Text', 'TextInput', 0, 1, exp_domain.EXPLICIT_CLASSIFICATION, {},
         'sess', 10.5)
     self.assertEqual(
         submitted_answer.to_dict(), {
             'answer': 'Text',
             'interaction_id': 'TextInput',
             'answer_group_index': 0,
             'rule_spec_index': 1,
             'classification_categorization':
             exp_domain.EXPLICIT_CLASSIFICATION,
             'params': {},
             'session_id': 'sess',
             'time_spent_in_sec': 10.5
         })
Пример #13
0
 def test_can_be_converted_to_from_full_dict(self):
     submitted_answer = stats_domain.SubmittedAnswer(
         'Text',
         'TextInput',
         0,
         1,
         exp_domain.EXPLICIT_CLASSIFICATION, {},
         'sess',
         10.5,
         rule_spec_str='rule spec str',
         answer_str='answer str')
     submitted_answer_dict = submitted_answer.to_dict()
     cloned_submitted_answer = stats_domain.SubmittedAnswer.from_dict(
         submitted_answer_dict)
     self.assertEqual(cloned_submitted_answer.to_dict(),
                      submitted_answer_dict)
Пример #14
0
    def _handle_event(cls, exploration_id, exploration_version, state_name,
                      interaction_id, answer_group_index, rule_spec_index,
                      classification_categorization, session_id,
                      time_spent_in_secs, params, normalized_answer):
        """Records an event when an answer triggers a rule. The answer recorded
        here is a Python-representation of the actual answer submitted by the
        user.
        """
        # TODO(sll): Escape these args?
        stats_services.record_answer(
            exploration_id, exploration_version, state_name, interaction_id,
            stats_domain.SubmittedAnswer(normalized_answer, interaction_id,
                                         answer_group_index, rule_spec_index,
                                         classification_categorization, params,
                                         session_id, time_spent_in_secs))

        feedback_is_useful = (classification_categorization !=
                              (exp_domain.DEFAULT_OUTCOME_CLASSIFICATION))

        stats_models.AnswerSubmittedEventLogEntryModel.create(
            exploration_id, exploration_version, state_name, session_id,
            time_spent_in_secs, feedback_is_useful)
Пример #15
0
    def test_record_answer_without_retrieving_it_first(self):
        stats_services.record_answer(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name, 'TextInput',
            stats_domain.SubmittedAnswer('first answer', 'TextInput', 0, 0,
                                         exp_domain.EXPLICIT_CLASSIFICATION,
                                         {}, 'a_session_id_val', 1.0))

        state_answers = stats_services.get_state_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertEqual(state_answers.get_submitted_answer_dict_list(),
                         [{
                             'answer': 'first answer',
                             'time_spent_in_sec': 1.0,
                             'answer_group_index': 0,
                             'rule_spec_index': 0,
                             'classification_categorization': 'explicit',
                             'session_id': 'a_session_id_val',
                             'interaction_id': 'TextInput',
                             'params': {}
                         }])
Пример #16
0
    def test_only_sample_answers_in_main_shard_returned(self):
        # Use a smaller max answer list size so fewer answers are needed to
        # exceed a shard.
        with self.swap(stats_models.StateAnswersModel,
                       '_MAX_ANSWER_LIST_BYTE_SIZE', 15000):
            state_answers = stats_services.get_state_answers(
                self.EXP_ID, self.exploration.version,
                self.exploration.init_state_name)
            self.assertIsNone(state_answers)

            submitted_answer_list = [
                stats_domain.SubmittedAnswer(
                    'answer ccc', 'TextInput', 1, 1,
                    exp_domain.EXPLICIT_CLASSIFICATION, {}, 'session_id_v',
                    3.0),
            ]
            stats_services.record_answers(self.EXP_ID,
                                          self.exploration.version,
                                          self.exploration.init_state_name,
                                          'TextInput',
                                          submitted_answer_list * 100)

        # Verify more than 1 shard was stored. The index shard (shard_id 0)
        # is not included in the shard count. Since a total of 100 answers were
        # submitted, there must therefore be fewer than 100 answers in the
        # index shard.
        model = stats_models.StateAnswersModel.get(
            '%s:%s:%s:%s' %
            (self.exploration.id, str(self.exploration.version),
             self.exploration.init_state_name, '0'))
        self.assertEqual(model.shard_count, 1)

        # Verify that the list of sample answers returned contains fewer than
        # 100 answers, although a total of 100 answers were submitted.
        sample_answers = stats_services.get_sample_answers(
            self.EXP_ID, self.exploration.version,
            self.exploration.init_state_name)
        self.assertLess(len(sample_answers), 100)
Пример #17
0
 def test_can_retrieve_properly_constructed_submitted_answer_dict_list(
         self):
     state_answers = stats_domain.StateAnswers(
         'exp_id', 1, 'initial_state', 'TextInput', [
             stats_domain.SubmittedAnswer(
                 'Text',
                 'TextInput',
                 0,
                 1,
                 exp_domain.EXPLICIT_CLASSIFICATION, {},
                 'sess',
                 10.5,
                 rule_spec_str='rule spec str1',
                 answer_str='answer str1'),
             stats_domain.SubmittedAnswer(
                 'Other text',
                 'TextInput',
                 1,
                 0,
                 exp_domain.DEFAULT_OUTCOME_CLASSIFICATION, {},
                 'sess',
                 7.5,
                 rule_spec_str='rule spec str2',
                 answer_str='answer str2')
         ])
     submitted_answer_dict_list = (
         state_answers.get_submitted_answer_dict_list())
     self.assertEqual(submitted_answer_dict_list,
                      [{
                          'answer': 'Text',
                          'interaction_id': 'TextInput',
                          'answer_group_index': 0,
                          'rule_spec_index': 1,
                          'classification_categorization':
                          exp_domain.EXPLICIT_CLASSIFICATION,
                          'params': {},
                          'session_id': 'sess',
                          'time_spent_in_sec': 10.5,
                          'rule_spec_str': 'rule spec str1',
                          'answer_str': 'answer str1'
                      }, {
                          'answer':
                          'Other text',
                          'interaction_id':
                          'TextInput',
                          'answer_group_index':
                          1,
                          'rule_spec_index':
                          0,
                          'classification_categorization':
                          (exp_domain.DEFAULT_OUTCOME_CLASSIFICATION),
                          'params': {},
                          'session_id':
                          'sess',
                          'time_spent_in_sec':
                          7.5,
                          'rule_spec_str':
                          'rule spec str2',
                          'answer_str':
                          'answer str2'
                      }])