Пример #1
0
def get_problem_list(request):
    """
    Get the list of problems that need grading in course request.GET['course_id'].

    Returns:
        list of dicts with keys
           'location'
           'problem_name'
           'num_graded' -- number graded
           'num_pending' -- number pending in the queue
           'min_for_ml' -- minimum needed to make ML model
    """

    if request.method!="GET":
        error_message="Request needs to be GET."
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    course_id=request.GET.get("course_id")

    if not course_id:
        error_message="Missing needed tag course_id"
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    locations_for_course = [x['location'] for x in
                            list(Submission.objects.filter(course_id=course_id).values('location').distinct())]

    if len(locations_for_course)==0:
        error_message="No problems associated with course."
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    location_info=[]
    for location in locations_for_course:
        problem_name = Submission.objects.filter(location=location)[0].problem_id
        submissions_pending = staff_grading_util.submissions_pending_instructor(location, state_in=[SubmissionState.waiting_to_be_graded]).count()
        finished_instructor_graded = staff_grading_util.finished_submissions_graded_by_instructor(location).count()
        min_scored_for_location=settings.MIN_TO_USE_PEER
        location_ml_count = Submission.objects.filter(location=location, preferred_grader_type="ML").count()
        if location_ml_count>0:
            min_scored_for_location=settings.MIN_TO_USE_ML

        submissions_required = max([0,min_scored_for_location-finished_instructor_graded])

        problem_name_from_location=location.split("://")[1]
        location_dict={
            'location' : location,
            'problem_name' : problem_name,
            'problem_name_from_location' : problem_name_from_location,
            'num_graded' : finished_instructor_graded,
            'num_pending' : submissions_pending,
            'num_required' : submissions_required,
            'min_for_ml' : settings.MIN_TO_USE_ML,
            }
        location_info.append(location_dict)

    util.log_connection_data()
    return util._success_response({'problem_list' : location_info},
                                  _INTERFACE_VERSION)
Пример #2
0
def get_next_submission(request):
    """
    Supports GET request with the following arguments:
    course_id -- the course for which to return a submission.
    grader_id -- LMS user_id of the requesting user

    Returns json dict with the following keys:

    version: '1'  (number)

    success: bool

    if success:
      'submission_id': a unique identifier for the submission, to be passed
                       back with the grade.

      'submission': the submission, rendered as read-only html for grading

      'rubric': the rubric, also rendered as html.

      'prompt': the question prompt, also rendered as html.

      'message': if there was no submission available, but nothing went wrong,
                there will be a message field.
    else:
      'error': if success is False, will have an error message with more info.
    }
    """

    if request.method != "GET":
        raise Http404

    course_id = request.GET.get('course_id')
    grader_id = request.GET.get('grader_id')
    location = request.GET.get('location')

    log.debug(
        "Getting next submission for instructor grading for course: {0}.".
        format(course_id))

    if not (course_id or location) or not grader_id:

        return util._error_response("required_parameter_missing",
                                    _INTERFACE_VERSION)

    if location:
        (
            found, id
        ) = staff_grading_util.get_single_instructor_grading_item_for_location(
            location)

    # TODO: save the grader id and match it in save_grade to make sure things
    # are consistent.
    if not location:
        (found,
         id) = staff_grading_util.get_single_instructor_grading_item(course_id)

    if not found:
        return util._success_response(
            {'message': 'No more submissions to grade.'}, _INTERFACE_VERSION)

    try:
        submission = Submission.objects.get(id=int(id))
    except Submission.DoesNotExist:
        log.error("Couldn't find submission %s for instructor grading", id)
        return util._error_response('failed_to_load_submission',
                                    _INTERFACE_VERSION,
                                    data={'submission_id': id})

    #Get error metrics from ml grading, and get into dictionary form to pass down to staff grading view
    success, ml_error_info = ml_grading_util.get_ml_errors(submission.location)
    if success:
        ml_error_message = staff_grading_util.generate_ml_error_message(
            ml_error_info)
    else:
        ml_error_message = ml_error_info

    ml_error_message = "Machine learning error information: " + ml_error_message

    if submission.state != 'C':
        log.error(
            "Instructor grading got a submission (%s) in an invalid state: ",
            id, submission.state)
        return util._error_response('wrong_internal_state',
                                    _INTERFACE_VERSION,
                                    data={
                                        'submission_id': id,
                                        'submission_state': submission.state
                                    })

    num_graded, num_pending = staff_grading_util.count_submissions_graded_and_pending_instructor(
        submission.location)

    response = {
        'submission_id':
        id,
        'submission':
        submission.student_response,
        'rubric':
        submission.rubric,
        'prompt':
        submission.prompt,
        'max_score':
        submission.max_score,
        'ml_error_info':
        ml_error_message,
        'problem_name':
        submission.problem_id,
        'num_graded':
        staff_grading_util.finished_submissions_graded_by_instructor(
            submission.location).count(),
        'num_pending':
        staff_grading_util.submissions_pending_instructor(
            submission.location,
            state_in=[SubmissionState.waiting_to_be_graded]).count(),
        'min_for_ml':
        settings.MIN_TO_USE_ML,
    }

    util.log_connection_data()
    log.debug("Sending success response back to instructor grading!")
    log.debug("Sub id from get next: {0}".format(submission.id))
    return util._success_response(response, _INTERFACE_VERSION)
Пример #3
0
def get_problem_list(request):
    """
    Get the list of problems that need grading in course request.GET['course_id'].

    Returns:
        list of dicts with keys
           'location'
           'problem_name'
           'num_graded' -- number graded
           'num_pending' -- number pending in the queue
           'min_for_ml' -- minimum needed to make ML model
    """

    if request.method != "GET":
        error_message = "Request needs to be GET."
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    course_id = request.GET.get("course_id")

    if not course_id:
        error_message = "Missing needed tag course_id"
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    locations_for_course = [
        x['location'] for x in list(
            Submission.objects.filter(
                course_id=course_id).values('location').distinct())
    ]

    if len(locations_for_course) == 0:
        error_message = "No problems associated with course."
        log.error(error_message)
        return util._error_response(error_message, _INTERFACE_VERSION)

    location_info = []
    for location in locations_for_course:
        problem_name = Submission.objects.filter(
            location=location)[0].problem_id
        submissions_pending = staff_grading_util.submissions_pending_instructor(
            location, state_in=[SubmissionState.waiting_to_be_graded]).count()
        finished_instructor_graded = staff_grading_util.finished_submissions_graded_by_instructor(
            location).count()
        min_scored_for_location = settings.MIN_TO_USE_PEER
        location_ml_count = Submission.objects.filter(
            location=location, preferred_grader_type="ML").count()
        if location_ml_count > 0:
            min_scored_for_location = settings.MIN_TO_USE_ML

        submissions_required = max(
            [0, min_scored_for_location - finished_instructor_graded])

        problem_name_from_location = location.split("://")[1]
        location_dict = {
            'location': location,
            'problem_name': problem_name,
            'problem_name_from_location': problem_name_from_location,
            'num_graded': finished_instructor_graded,
            'num_pending': submissions_pending,
            'num_required': submissions_required,
            'min_for_ml': settings.MIN_TO_USE_ML,
        }
        location_info.append(location_dict)

    util.log_connection_data()
    log.debug(location_info)
    return util._success_response({'problem_list': location_info},
                                  _INTERFACE_VERSION)
Пример #4
0
def get_next_submission(request):
    """
    Supports GET request with the following arguments:
    course_id -- the course for which to return a submission.
    grader_id -- LMS user_id of the requesting user

    Returns json dict with the following keys:

    version: '1'  (number)

    success: bool

    if success:
      'submission_id': a unique identifier for the submission, to be passed
                       back with the grade.

      'submission': the submission, rendered as read-only html for grading

      'rubric': the rubric, also rendered as html.

      'prompt': the question prompt, also rendered as html.

      'message': if there was no submission available, but nothing went wrong,
                there will be a message field.
    else:
      'error': if success is False, will have an error message with more info.
    }
    """

    if request.method != "GET":
        raise Http404

    course_id = request.GET.get('course_id')
    grader_id = request.GET.get('grader_id')
    location = request.GET.get('location')


    if not (course_id or location) or not grader_id:
   
        return util._error_response("required_parameter_missing", _INTERFACE_VERSION)

    if location:
        (found, id) = staff_grading_util.get_single_instructor_grading_item_for_location(location)

    # TODO: save the grader id and match it in save_grade to make sure things
    # are consistent.
    if not location:
        (found, id) = staff_grading_util.get_single_instructor_grading_item(course_id)

    if not found:
        return util._success_response({'message': 'No more submissions to grade.'},
                                      _INTERFACE_VERSION)

    try:
        submission = Submission.objects.get(id=int(id))
    except Submission.DoesNotExist:
        log.error("Couldn't find submission %s for instructor grading", id)
        return util._error_response('failed_to_load_submission',
                                    _INTERFACE_VERSION,
                                    data={'submission_id': id})

    #Get error metrics from ml grading, and get into dictionary form to pass down to staff grading view
    success, ml_error_info=ml_grading_util.get_ml_errors(submission.location)
    if success:
        ml_error_message=staff_grading_util.generate_ml_error_message(ml_error_info)
    else:
        ml_error_message=ml_error_info

    ml_error_message="Machine learning error information: " + ml_error_message

    if submission.state != 'C':
        log.error("Instructor grading got a submission (%s) in an invalid state: ",
            id, submission.state)
        return util._error_response('wrong_internal_state',
                                    _INTERFACE_VERSION,
                                    data={'submission_id': id,
                                     'submission_state': submission.state})

    num_graded, num_pending = staff_grading_util.count_submissions_graded_and_pending_instructor(submission.location)

    response = {'submission_id': id,
                'submission': submission.student_response,
                'rubric': submission.rubric,
                'prompt': submission.prompt,
                'max_score': submission.max_score,
                'ml_error_info' : ml_error_message,
                'problem_name' : submission.problem_id,
                'num_graded' : staff_grading_util.finished_submissions_graded_by_instructor(submission.location).count(),
                'num_pending' : staff_grading_util.submissions_pending_instructor(submission.location, 
                                    state_in=[SubmissionState.waiting_to_be_graded]).count(),
                'min_for_ml' : settings.MIN_TO_USE_ML,
                }

    util.log_connection_data()
    return util._success_response(response, _INTERFACE_VERSION)