示例#1
0
    def handle(self, *args, **options):
        """
        Run the command.
        """
        if not args:
            raise CommandError("Course ID must be specified to fetch data")

        course_id = args[0]

        if options['file_name']:
            file_name = options['file_name']
        else:
            file_name = ("%s-ora2.csv" % course_id).replace("/", "-")

        if options['output_dir']:
            csv_file = open(os.path.join(options['output_dir'], file_name), 'wb')
        else:
            csv_file = self.stdout

        writer = csv.writer(csv_file, dialect='excel', quotechar='"', quoting=csv.QUOTE_ALL)

        header, rows = OraAggregateData.collect_ora2_data(course_id)

        writer.writerow(header)
        for row in rows:
            writer.writerow(_encode_row(row))
示例#2
0
    def handle(self, *args, **options):
        """
        Run the command.
        """
        if not options['course_id']:
            raise CommandError("Course ID must be specified to fetch data")

        course_id = options['course_id']

        if options['file_name']:
            file_name = options['file_name']
        else:
            file_name = ("%s-ora2.csv" % course_id).replace("/", "-")

        if options['output_dir']:
            csv_file = open(os.path.join(options['output_dir'], file_name), 'wb')
        else:
            csv_file = self.stdout

        writer = csv.writer(csv_file, dialect='excel', quotechar='"', quoting=csv.QUOTE_ALL)

        header, rows = OraAggregateData.collect_ora2_data(course_id)

        writer.writerow(header)
        for row in rows:
            writer.writerow(_encode_row(row))
    def test_collect_ora2_data_with_special_characters(self, answer):
        """
        Scenario: Verify the data collection for ORA2 works with special or non-ascii characters.

        Given the submission object
        Then update its answer with a non-ascii value
        And the submission is saved
        When the ORA2 data for the submissions is obtained
        Then the data's answer will be same as json dumped answer
        """
        submission = sub_api._get_submission_model(self.submission['uuid'])  # pylint: disable=protected-access
        submission.answer = answer
        submission.save()
        _, rows = OraAggregateData.collect_ora2_data(COURSE_ID)
        self.assertEqual(json.dumps(answer, ensure_ascii=False), rows[1][4])
示例#4
0
    def test_collect_ora2_data_with_special_characters(self, answer):
        """
        Scenario: Verify the data collection for ORA2 works with special or non-ascii characters.

        Given the submission object
        Then update its answer with a non-ascii value
        And the submission is saved
        When the ORA2 data for the submissions is obtained
        Then the data's answer will be same as json dumped answer
        """
        submission = sub_api._get_submission_model(self.submission['uuid'])  # pylint: disable=protected-access
        submission.answer = answer
        submission.save()
        with patch(
                'openassessment.data.OraAggregateData._map_anonymized_ids_to_usernames'
        ) as map_mock:
            map_mock.return_value = USERNAME_MAPPING
            _, rows = OraAggregateData.collect_ora2_data(COURSE_ID)
        self.assertEqual(json.dumps(answer, ensure_ascii=False), rows[1][7])
示例#5
0
def upload_ora2_data(
        _xmodule_instance_args, _entry_id, course_id, _task_input, action_name
):
    """
    Collect ora2 responses and upload them to S3 as a CSV
    """

    start_date = datetime.now(UTC)
    start_time = time()

    num_attempted = 1
    num_total = 1

    fmt = u'Task: {task_id}, InstructorTask ID: {entry_id}, Course: {course_id}, Input: {task_input}'
    task_info_string = fmt.format(
        task_id=_xmodule_instance_args.get('task_id') if _xmodule_instance_args is not None else None,
        entry_id=_entry_id,
        course_id=course_id,
        task_input=_task_input
    )
    TASK_LOG.info(u'%s, Task type: %s, Starting task execution', task_info_string, action_name)

    task_progress = TaskProgress(action_name, num_total, start_time)
    task_progress.attempted = num_attempted

    curr_step = {'step': "Collecting responses"}
    TASK_LOG.info(
        u'%s, Task type: %s, Current step: %s for all submissions',
        task_info_string,
        action_name,
        curr_step,
    )

    task_progress.update_task_state(extra_meta=curr_step)

    try:
        header, datarows = OraAggregateData.collect_ora2_data(course_id)
        rows = [header] + [row for row in datarows]
    # Update progress to failed regardless of error type
    except Exception:  # pylint: disable=broad-except
        TASK_LOG.exception('Failed to get ORA data.')
        task_progress.failed = 1
        curr_step = {'step': "Error while collecting data"}

        task_progress.update_task_state(extra_meta=curr_step)

        return UPDATE_STATUS_FAILED

    task_progress.succeeded = 1
    curr_step = {'step': "Uploading CSV"}
    TASK_LOG.info(
        u'%s, Task type: %s, Current step: %s',
        task_info_string,
        action_name,
        curr_step,
    )
    task_progress.update_task_state(extra_meta=curr_step)

    upload_csv_to_report_store(rows, 'ORA_data', course_id, start_date)

    curr_step = {'step': 'Finalizing ORA data report'}
    task_progress.update_task_state(extra_meta=curr_step)
    TASK_LOG.info(u'%s, Task type: %s, Upload complete.', task_info_string, action_name)

    return UPDATE_STATUS_SUCCEEDED
示例#6
0
    def test_collect_ora2_data(self):
        headers, data = OraAggregateData.collect_ora2_data(COURSE_ID)

        self.assertEqual(headers, [
            'Submission ID',
            'Item ID',
            'Anonymized Student ID',
            'Date/Time Response Submitted',
            'Response',
            'Assessment Details',
            'Assessment Scores',
            'Date/Time Final Score Given',
            'Final Score Points Earned',
            'Final Score Points Possible',
            'Feedback Statements Selected',
            'Feedback on Peer Assessments'
        ])


        self.assertEqual(data[0], [
            self.scorer_submission['uuid'],
            self.scorer_submission['student_item'],
            SCORER_ID,
            self.scorer_submission['submitted_at'],
            self.scorer_submission['answer'],
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
        ])

        self.assertEqual(data[1], [
            self.submission['uuid'],
            self.submission['student_item'],
            STUDENT_ID,
            self.submission['submitted_at'],
            self.submission['answer'],
            u"Assessment #{id}\n-- scored_at: {scored_at}\n-- type: PE\n".format(
                id=self.assessment['id'],
                scored_at=self.assessment['scored_at'],
            ) +
            u"-- scorer_id: {scorer}\n-- overall_feedback: {feedback}\n".format(
                scorer=self.assessment['scorer_id'],
                feedback=self.assessment['feedback']
            ),
            u"Assessment #{id}\n-- {label}: {option_label} ({points})\n".format(
                id=self.assessment['id'],
                label=self.assessment['parts'][1]['criterion']['label'],
                option_label=self.assessment['parts'][1]['criterion']['options'][0]['label'],
                points=self.assessment['parts'][1]['criterion']['options'][0]['points'],
            ) +
            u"-- {label}: {option_label} ({points})\n-- feedback: {feedback}\n".format(
                label=self.assessment['parts'][0]['criterion']['label'],
                option_label=self.assessment['parts'][0]['criterion']['options'][1]['label'],
                points=self.assessment['parts'][0]['criterion']['options'][1]['points'],
                feedback=self.assessment['parts'][0]['feedback'],
            ),
            self.score['created_at'],
            self.score['points_earned'],
            self.score['points_possible'],
            FEEDBACK_OPTIONS['options'][0] + '\n' + FEEDBACK_OPTIONS['options'][1]+'\n',
            FEEDBACK_TEXT,
        ])
示例#7
0
    def test_collect_ora2_data_when_usernames_disabled(self):
        """
        Tests that ``OraAggregateData.collect_ora2_data`` generated report
        without usernames when `ENABLE_ORA_USERNAMES_ON_DATA_EXPORT`
        settings toggle equals ``False``.
        """

        with patch.dict('django.conf.settings.FEATURES',
                        {'ENABLE_ORA_USERNAMES_ON_DATA_EXPORT': False}):
            headers, data = OraAggregateData.collect_ora2_data(COURSE_ID)

        self.assertEqual(headers, [
            'Submission ID', 'Location', 'Problem Name', 'Item ID',
            'Anonymized Student ID', 'Date/Time Response Submitted',
            'Response', 'Assessment Details', 'Assessment Scores',
            'Date/Time Final Score Given', 'Final Score Points Earned',
            'Final Score Points Possible', 'Feedback Statements Selected',
            'Feedback on Peer Assessments'
        ])
        self.assertEqual(data[0], [
            self.scorer_submission['uuid'],
            ITEM_ID,
            ITEM_DISPLAY_NAME,
            self.scorer_submission['student_item'],
            SCORER_ID,
            self.scorer_submission['submitted_at'],
            json.dumps(self.scorer_submission['answer']),
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
        ])
        self.assertEqual(data[1], [
            self.submission['uuid'],
            ITEM_ID,
            ITEM_DISPLAY_NAME,
            self.submission['student_item'],
            STUDENT_ID,
            self.submission['submitted_at'],
            json.dumps(self.submission['answer']),
            u"Assessment #{id}\n-- scored_at: {scored_at}\n-- type: PE\n".
            format(
                id=self.assessment['id'],
                scored_at=self.assessment['scored_at'],
            ) + u"-- scorer_id: {scorer_id}\n-- overall_feedback: {feedback}\n"
            .format(scorer_id=self.assessment['scorer_id'],
                    feedback=self.assessment['feedback']),
            u"Assessment #{id}\n-- {label}: {option_label} ({points})\n".
            format(
                id=self.assessment['id'],
                label=self.assessment['parts'][0]['criterion']['label'],
                option_label=self.assessment['parts'][0]['criterion']
                ['options'][0]['label'],
                points=self.assessment['parts'][0]['criterion']['options'][0]
                ['points'],
            ) +
            u"-- {label}: {option_label} ({points})\n-- feedback: {feedback}\n"
            .format(
                label=self.assessment['parts'][1]['criterion']['label'],
                option_label=self.assessment['parts'][1]['criterion']
                ['options'][1]['label'],
                points=self.assessment['parts'][1]['criterion']['options'][1]
                ['points'],
                feedback=self.assessment['parts'][1]['feedback'],
            ),
            self.score['created_at'],
            self.score['points_earned'],
            self.score['points_possible'],
            FEEDBACK_OPTIONS['options'][0] + '\n' +
            FEEDBACK_OPTIONS['options'][1] + '\n',
            FEEDBACK_TEXT,
        ])
示例#8
0
    def test_collect_ora2_data(self):
        with patch(
                'openassessment.data.OraAggregateData._map_anonymized_ids_to_usernames'
        ) as map_mock:
            map_mock.return_value = USERNAME_MAPPING
            headers, data = OraAggregateData.collect_ora2_data(COURSE_ID)

        self.assertEqual(headers, [
            'Submission ID', 'Location', 'Problem Name', 'Item ID', 'Username',
            'Anonymized Student ID', 'Date/Time Response Submitted',
            'Response', 'Assessment Details', 'Assessment Scores',
            'Date/Time Final Score Given', 'Final Score Points Earned',
            'Final Score Points Possible', 'Feedback Statements Selected',
            'Feedback on Peer Assessments'
        ])
        self.assertEqual(data[0], [
            self.scorer_submission['uuid'],
            ITEM_ID,
            ITEM_DISPLAY_NAME,
            self.scorer_submission['student_item'],
            SCORER_USERNAME,
            SCORER_ID,
            self.scorer_submission['submitted_at'],
            json.dumps(self.scorer_submission['answer']),
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
            u'',
        ])
        self.assertEqual(data[1], [
            self.submission['uuid'],
            ITEM_ID,
            ITEM_DISPLAY_NAME,
            self.submission['student_item'],
            STUDENT_USERNAME,
            STUDENT_ID,
            self.submission['submitted_at'],
            json.dumps(self.submission['answer']),
            u"Assessment #{id}\n-- scored_at: {scored_at}\n-- type: PE\n".
            format(
                id=self.assessment['id'],
                scored_at=self.assessment['scored_at'],
            ) + u"-- scorer_username: {scorer_username}\n".format(
                scorer_username=USERNAME_MAPPING[self.assessment['scorer_id']])
            + u"-- scorer_id: {scorer_id}\n-- overall_feedback: {feedback}\n".
            format(scorer_id=self.assessment['scorer_id'],
                   feedback=self.assessment['feedback']),
            u"Assessment #{id}\n-- {label}: {option_label} ({points})\n".
            format(
                id=self.assessment['id'],
                label=self.assessment['parts'][0]['criterion']['label'],
                option_label=self.assessment['parts'][0]['criterion']
                ['options'][0]['label'],
                points=self.assessment['parts'][0]['criterion']['options'][0]
                ['points'],
            ) +
            u"-- {label}: {option_label} ({points})\n-- feedback: {feedback}\n"
            .format(
                label=self.assessment['parts'][1]['criterion']['label'],
                option_label=self.assessment['parts'][1]['criterion']
                ['options'][1]['label'],
                points=self.assessment['parts'][1]['criterion']['options'][1]
                ['points'],
                feedback=self.assessment['parts'][1]['feedback'],
            ),
            self.score['created_at'],
            self.score['points_earned'],
            self.score['points_possible'],
            FEEDBACK_OPTIONS['options'][0] + '\n' +
            FEEDBACK_OPTIONS['options'][1] + '\n',
            FEEDBACK_TEXT,
        ])