def test_post_submission_for_student_on_accessing(self):
        course = get_course_with_access(self.student_on_accessing, 'load', self.course_id)

        dry_run_result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=True)
        self.assertFalse(dry_run_result)

        with patch('capa.xqueue_interface.XQueueInterface.send_to_queue') as mock_send_to_queue:
            mock_send_to_queue.return_value = (0, "Successfully queued")

            module = get_module_for_student(self.student_on_accessing, self.problem_location)
            task = module.child_module.get_task_number(self.open_ended_task_number)

            student_response = "Here is an answer."
            student_anonymous_id = anonymous_id_for_user(self.student_on_accessing, None)
            submission_time = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)

            result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=False)

            self.assertTrue(result)
            mock_send_to_queue_body_arg = json.loads(mock_send_to_queue.call_args[1]['body'])
            self.assertEqual(mock_send_to_queue_body_arg['max_score'], 2)
            self.assertEqual(mock_send_to_queue_body_arg['student_response'], student_response)
            body_arg_student_info = json.loads(mock_send_to_queue_body_arg['student_info'])
            self.assertEqual(body_arg_student_info['anonymous_student_id'], student_anonymous_id)
            self.assertGreaterEqual(body_arg_student_info['submission_time'], submission_time)
    def test_post_submission_for_student_on_accessing(self):
        course = get_course_with_access(self.student_on_accessing, self.course_id, "load")

        dry_run_result = post_submission_for_student(
            self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=True
        )
        self.assertFalse(dry_run_result)

        with patch("capa.xqueue_interface.XQueueInterface.send_to_queue") as mock_send_to_queue:
            mock_send_to_queue.return_value = (0, "Successfully queued")

            module = get_module_for_student(self.student_on_accessing, course, self.problem_location)
            task = module.child_module.get_task_number(self.open_ended_task_number)

            qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)
            student_info = {
                "anonymous_student_id": anonymous_id_for_user(self.student_on_accessing, ""),
                "submission_time": qtime,
            }

            contents = task.payload.copy()
            contents.update(
                {"max_score": 2, "student_info": json.dumps(student_info), "student_response": "Here is an answer."}
            )

            result = post_submission_for_student(
                self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=False
            )
            self.assertTrue(result)
            mock_send_to_queue.assert_called_with(body=json.dumps(contents), header=ANY)
示例#3
0
    def test_post_submission_for_student_on_accessing(self):
        course = get_course_with_access(self.student_on_accessing, self.course_id, 'load')

        dry_run_result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=True)
        self.assertFalse(dry_run_result)

        with patch('capa.xqueue_interface.XQueueInterface.send_to_queue') as mock_send_to_queue:
            mock_send_to_queue.return_value = (0, "Successfully queued")

            module = get_module_for_student(self.student_on_accessing, course, self.problem_location)
            task = module.child_module.get_task_number(self.open_ended_task_number)

            qtime = datetime.strftime(datetime.now(UTC), xqueue_interface.dateformat)
            student_info = {'anonymous_student_id': anonymous_id_for_user(self.student_on_accessing, ''),
                            'submission_time': qtime}

            contents = task.payload.copy()
            contents.update({
                'max_score': 2,
                'student_info': json.dumps(student_info),
                'student_response': "Here is an answer.",
            })

            result = post_submission_for_student(self.student_on_accessing, course, self.problem_location, self.open_ended_task_number, dry_run=False)
            self.assertTrue(result)
            mock_send_to_queue.assert_called_with(body=json.dumps(contents), header=ANY)
示例#4
0
    def get_raw(self, command="all"):
        """Get raw data of progress."""
        if not OPERATION.has_key(command):
            log.error('Invalid command: {}'.format(command))
            raise InvalidCommand("Invalid command: {}".format(command))

        if command == "summary":
            return self.courseware_summary

        self.courseware_summary["graded_students"] = 0
        student_count = 0
        for student in self.students.iterator():
            student_count += 1
            if (student_count % 100
                    == 0) or (student_count
                              == self.courseware_summary['active_students']):
                msg = "Progress %d/%d" % (
                    student_count, self.courseware_summary['active_students'])

                if self.update_state is not None:
                    self.update_state(state=msg)

                log.info(msg)

            self.request.user = student
            log.debug(" * Active user: {}".format(student))
            grade = grades.grade(student, self.request, self.course)

            if grade["grade"] is not None:
                self.courseware_summary["graded_students"] += 1

            for category in self.location_list.keys():
                if category not in ["problem"]:
                    continue

                for loc in self.location_list[category]:
                    log.debug(" * Active location: {}".format(loc))
                    module = get_module_for_student(student, loc)

                    if module is None:
                        log.debug(" * No state found: %s" % (student))
                        continue

                    self.collect_module_summary(module)

        cache.set('progress_summary',
                  self.courseware_summary["graded_students"],
                  timeout=24 * 60 * 60)

        #statistics = self._calc_statistics()
        #for key in statistics.keys():
        #    self.module_summary[key].update(statistics[key])

        if command == "modules":
            return self.module_summary

        return self.courseware_summary, self.module_summary
示例#5
0
def post_submission_for_student(student,
                                course,
                                location,
                                task_number,
                                dry_run=True,
                                hostname=None):
    """If the student's task child_state is ASSESSING post submission to grader."""

    print "{0}:{1}".format(student.id, student.username)

    request = DummyRequest()
    request.user = student
    request.host = hostname

    try:
        module = get_module_for_student(student,
                                        course,
                                        location,
                                        request=request)
        if module is None:
            print "  WARNING: No state found."
            return False

        latest_task = module.child_module.get_task_number(task_number)
        if latest_task is None:
            print "  WARNING: No task state found."
            return False

        if not isinstance(latest_task, OpenEndedModule):
            print " ERROR: Not an OpenEndedModule task."
            return False

        latest_task_state = latest_task.child_state

        if latest_task_state == OpenEndedChild.INITIAL:
            print "  WARNING: No submission."
        elif latest_task_state == OpenEndedChild.POST_ASSESSMENT or latest_task_state == OpenEndedChild.DONE:
            print "  WARNING: Submission already graded."
        elif latest_task_state == OpenEndedChild.ASSESSING:
            latest_answer = latest_task.latest_answer()
            if dry_run:
                print "  Skipped sending submission to grader: {0!r}".format(
                    latest_answer[:100].encode('utf-8'))
            else:
                latest_task.send_to_grader(latest_answer, latest_task.system)
                print "  Sent submission to grader: {0!r}".format(
                    latest_answer[:100].encode('utf-8'))
                return True
        else:
            print "WARNING: Invalid task_state: {0}".format(latest_task_state)
    except Exception as err:  # pylint: disable=broad-except
        print err

    return False
示例#6
0
    def yield_students_progress(self):
        """Yield progress of students as CSV row."""
        header_flag = False
        student_count = 0
        for student in self.students.iterator():
            student_count += 1
            if (student_count % 100
                    == 0) or (student_count
                              == self.courseware_summary['active_students']):
                msg = "Progress %d/%d" % (
                    student_count, self.courseware_summary['active_students'])

                if self.update_state is not None:
                    self.update_state(state=msg)

                log.info(msg)

            self.request.user = student
            grade = grades.grade(student, self.request, self.course)

            for category in self.location_list.keys():
                if category not in ["problem"]:
                    continue

                for loc in self.location_list[category]:
                    module = get_module_for_student(student, loc)

                    if module is None:
                        log.debug(" * No state found: %s" % (student))
                        continue

                    module_data = self._get_module_data(module)
                    csvrow = [
                        student.username, module.location,
                        student.last_login.strftime("%Y/%m/%d %H:%M:%S %Z"),
                        grade["grade"], grade["percent"]
                    ]

                    if header_flag is False:
                        header = [
                            "username", "location", "last_login", "grade",
                            "percent"
                        ]
                        for key in module_data.keys():
                            header.append(key)
                        header_flag = True
                        yield header

                    for key in module_data.keys():
                        csvrow.append(module_data[key])

                    yield csvrow
示例#7
0
def post_submission_for_student(student, course, location, task_number, dry_run=True, hostname=None):
    """If the student's task child_state is ASSESSING post submission to grader."""

    print "{0}:{1}".format(student.id, student.username)

    request = DummyRequest()
    request.user = student
    request.host = hostname

    try:
        module = get_module_for_student(student, location, request=request)
        if module is None:
            print "  WARNING: No state found."
            return False

        latest_task = module.child_module.get_task_number(task_number)
        if latest_task is None:
            print "  WARNING: No task state found."
            return False

        if not isinstance(latest_task, OpenEndedModule):
            print " ERROR: Not an OpenEndedModule task."
            return False

        latest_task_state = latest_task.child_state

        if latest_task_state == OpenEndedChild.INITIAL:
            print "  WARNING: No submission."
        elif latest_task_state == OpenEndedChild.POST_ASSESSMENT or latest_task_state == OpenEndedChild.DONE:
            print "  WARNING: Submission already graded."
        elif latest_task_state == OpenEndedChild.ASSESSING:
            latest_answer = latest_task.latest_answer()
            if dry_run:
                print "  Skipped sending submission to grader: {0!r}".format(latest_answer[:100].encode('utf-8'))
            else:
                latest_task.send_to_grader(latest_answer, latest_task.system)
                print "  Sent submission to grader: {0!r}".format(latest_answer[:100].encode('utf-8'))
                return True
        else:
            print "WARNING: Invalid task_state: {0}".format(latest_task_state)
    except Exception as err:  # pylint: disable=broad-except
        print err

    return False
def calculate_task_statistics(students, course, location, task_number, write_to_file=True):
    """Print stats of students."""

    stats = {
        OpenEndedChild.INITIAL: 0,
        OpenEndedChild.ASSESSING: 0,
        OpenEndedChild.POST_ASSESSMENT: 0,
        OpenEndedChild.DONE: 0
    }

    students_with_saved_answers = []
    students_with_ungraded_submissions = []  # pylint: disable=invalid-name
    students_with_graded_submissions = []  # pylint: disable=invalid-name
    students_with_no_state = []

    student_modules = StudentModule.objects.filter(module_state_key=location, student__in=students).order_by('student')
    print "Total student modules: {0}".format(student_modules.count())

    for index, student_module in enumerate(student_modules):
        if index % 100 == 0:
            print "--- {0} students processed ---".format(index)

        student = student_module.student
        print "{0}:{1}".format(student.id, student.username)

        module = get_module_for_student(student, course, location)
        if module is None:
            print "  WARNING: No state found"
            students_with_no_state.append(student)
            continue

        latest_task = module.child_module.get_task_number(task_number)
        if latest_task is None:
            print "  No task state found"
            students_with_no_state.append(student)
            continue

        task_state = latest_task.child_state
        stats[task_state] += 1
        print "  State: {0}".format(task_state)

        if task_state == OpenEndedChild.INITIAL:
            if latest_task.stored_answer is not None:
                students_with_saved_answers.append(student)
        elif task_state == OpenEndedChild.ASSESSING:
            students_with_ungraded_submissions.append(student)
        elif task_state == OpenEndedChild.POST_ASSESSMENT or task_state == OpenEndedChild.DONE:
            students_with_graded_submissions.append(student)

    location = Location(location)

    print "----------------------------------"
    print "Time: {0}".format(time.strftime("%Y %b %d %H:%M:%S +0000", time.gmtime()))
    print "Course: {0}".format(course.id)
    print "Location: {0}".format(location)
    print "No state: {0}".format(len(students_with_no_state))
    print "Initial State: {0}".format(stats[OpenEndedChild.INITIAL] - len(students_with_saved_answers))
    print "Saved answers: {0}".format(len(students_with_saved_answers))
    print "Submitted answers: {0}".format(stats[OpenEndedChild.ASSESSING])
    print "Received grades: {0}".format(stats[OpenEndedChild.POST_ASSESSMENT] + stats[OpenEndedChild.DONE])
    print "----------------------------------"

    if write_to_file:
        filename = "stats.{0}.{1}".format(location.course, location.name)
        time_stamp = time.strftime("%Y%m%d-%H%M%S")
        with open('{0}.{1}.csv'.format(filename, time_stamp), 'wb') as csv_file:
            writer = csv.writer(csv_file, delimiter=' ', quoting=csv.QUOTE_MINIMAL)
            for student in students_with_ungraded_submissions:
                writer.writerow(("ungraded", student.id, anonymous_id_for_user(student, ''), student.username))
            for student in students_with_graded_submissions:
                writer.writerow(("graded", student.id, anonymous_id_for_user(student, ''), student.username))
    return stats
示例#9
0
def calculate_task_statistics(students, course, location, task_number, write_to_file=True):
    """Print stats of students."""

    stats = {
        OpenEndedChild.INITIAL: 0,
        OpenEndedChild.ASSESSING: 0,
        OpenEndedChild.POST_ASSESSMENT: 0,
        OpenEndedChild.DONE: 0
    }

    students_with_saved_answers = []
    students_with_ungraded_submissions = []  # pylint: disable=invalid-name
    students_with_graded_submissions = []  # pylint: disable=invalid-name
    students_with_no_state = []

    student_modules = StudentModule.objects.filter(module_state_key=location, student__in=students).order_by('student')
    print "Total student modules: {0}".format(student_modules.count())

    for index, student_module in enumerate(student_modules):
        if index % 100 == 0:
            print "--- {0} students processed ---".format(index)

        student = student_module.student
        print "{0}:{1}".format(student.id, student.username)

        module = get_module_for_student(student, location)
        if module is None:
            print "  WARNING: No state found"
            students_with_no_state.append(student)
            continue

        latest_task = module.child_module.get_task_number(task_number)
        if latest_task is None:
            print "  No task state found"
            students_with_no_state.append(student)
            continue

        task_state = latest_task.child_state
        stats[task_state] += 1
        print "  State: {0}".format(task_state)

        if task_state == OpenEndedChild.INITIAL:
            if latest_task.stored_answer is not None:
                students_with_saved_answers.append(student)
        elif task_state == OpenEndedChild.ASSESSING:
            students_with_ungraded_submissions.append(student)
        elif task_state == OpenEndedChild.POST_ASSESSMENT or task_state == OpenEndedChild.DONE:
            students_with_graded_submissions.append(student)

    print "----------------------------------"
    print "Time: {0}".format(time.strftime("%Y %b %d %H:%M:%S +0000", time.gmtime()))
    print "Course: {0}".format(course.id)
    print "Location: {0}".format(location)
    print "No state: {0}".format(len(students_with_no_state))
    print "Initial State: {0}".format(stats[OpenEndedChild.INITIAL] - len(students_with_saved_answers))
    print "Saved answers: {0}".format(len(students_with_saved_answers))
    print "Submitted answers: {0}".format(stats[OpenEndedChild.ASSESSING])
    print "Received grades: {0}".format(stats[OpenEndedChild.POST_ASSESSMENT] + stats[OpenEndedChild.DONE])
    print "----------------------------------"

    if write_to_file:
        filename = "stats.{0}.{1}".format(location.course, location.name)
        time_stamp = time.strftime("%Y%m%d-%H%M%S")
        with open('{0}.{1}.csv'.format(filename, time_stamp), 'wb') as csv_file:
            writer = csv.writer(csv_file, delimiter=' ', quoting=csv.QUOTE_MINIMAL)
            for student in students_with_ungraded_submissions:
                writer.writerow(("ungraded", student.id, anonymous_id_for_user(student, None), student.username))
            for student in students_with_graded_submissions:
                writer.writerow(("graded", student.id, anonymous_id_for_user(student, None), student.username))
    return stats