Пример #1
0
def get_sequential_open_distrib(course_id, enrollment):
    """
    Returns the number of students that opened each subsection/sequential of the course

    `course_id` the course ID for the course interested in

    `enrollment` the number of students enrolled in this course.

    Outputs a dict mapping the 'module_id' to the number of students that have opened that subsection/sequential.
    """
    sequential_open_distrib = {}

    non_student_list = get_non_student_list(course_id)

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for "opening a subsection" data
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            module_type__exact='sequential',
        ).exclude(student_id__in=non_student_list).values(
            'module_state_key').annotate(
                count_sequential=Count('module_state_key'))

        for row in queryset:
            module_id = course_id.make_usage_key_from_deprecated_string(
                row['module_state_key'])
            sequential_open_distrib[module_id] = row['count_sequential']
    else:
        # Retrieve course object down to subsection
        course = modulestore().get_course(course_id, depth=2)

        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL,
                        auth_token=settings.ANALYTICS_DATA_TOKEN)

        for section in course.get_children():
            for subsection in section.get_children():
                module = client.modules(course_id, subsection.location)

                try:
                    sequential_open = module.sequential_open_distribution()
                except NotFoundError:
                    pass
                else:
                    sequential_open_distrib[
                        subsection.location] = sequential_open[0]['count']

    return sequential_open_distrib
Пример #2
0
def get_sequential_open_distrib(course_id, enrollment):
    """
    Returns the number of students that opened each subsection/sequential of the course

    `course_id` the course ID for the course interested in

    `enrollment` the number of students enrolled in this course.

    Outputs a dict mapping the 'module_id' to the number of students that have opened that subsection/sequential.
    """
    sequential_open_distrib = {}

    non_student_list = get_non_student_list(course_id)

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for "opening a subsection" data
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            module_type__exact='sequential',
        ).exclude(student_id__in=non_student_list).values('module_state_key').annotate(count_sequential=Count('module_state_key'))

        for row in queryset:
            module_id = course_id.make_usage_key_from_deprecated_string(row['module_state_key'])
            sequential_open_distrib[module_id] = row['count_sequential']
    else:
        # Retrieve course object down to subsection
        course = modulestore().get_course(course_id, depth=2)

        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL, auth_token=settings.ANALYTICS_DATA_TOKEN)

        for section in course.get_children():
            for subsection in section.get_children():
                module = client.modules(course_id, subsection.location)

                try:
                    sequential_open = module.sequential_open_distribution()
                except NotFoundError:
                    pass
                else:
                    sequential_open_distrib[subsection.location] = sequential_open[0]['count']

    return sequential_open_distrib
Пример #3
0
def get_problem_grade_distribution(course_id, enrollment):
    """
    Returns the grade distribution per problem for the course

    `course_id` the course ID for the course interested in

    `enrollment` the number of students enrolled in this course.

    Output is 2 dicts:
      'prob-grade_distrib' where the key is the problem 'module_id' and the value is a dict with:
        'max_grade' - max grade for this problem
        'grade_distrib' - array of tuples (`grade`,`count`).
      'total_student_count' where the key is problem 'module_id' and the value is number of students
        attempting the problem
    """
    non_student_list = get_non_student_list(course_id)

    prob_grade_distrib = {}
    total_student_count = defaultdict(int)

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for grade data for all problems in course
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            grade__isnull=False,
            module_type__in=PROB_TYPE_LIST,
        ).exclude(student_id__in=non_student_list).values(
            'module_state_key', 'grade',
            'max_grade').annotate(count_grade=Count('grade'))

        # Loop through resultset building data for each problem
        for row in queryset:
            curr_problem = course_id.make_usage_key_from_deprecated_string(
                row['module_state_key'])

            # Build set of grade distributions for each problem that has student responses
            if curr_problem in prob_grade_distrib:
                prob_grade_distrib[curr_problem]['grade_distrib'].append(
                    (row['grade'], row['count_grade']))

                if ((prob_grade_distrib[curr_problem]['max_grade'] !=
                     row['max_grade'])
                        and (prob_grade_distrib[curr_problem]['max_grade'] <
                             row['max_grade'])):
                    prob_grade_distrib[curr_problem]['max_grade'] = row[
                        'max_grade']

            else:
                prob_grade_distrib[curr_problem] = {
                    'max_grade': row['max_grade'],
                    'grade_distrib': [
                        (row['grade'], row['count_grade']),
                    ],
                }

            # Build set of total students attempting each problem
            total_student_count[curr_problem] += row['count_grade']
    else:
        # Retrieve course object down to problems
        course = modulestore().get_course(course_id, depth=4)

        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL,
                        auth_token=settings.ANALYTICS_DATA_TOKEN)

        for section in course.get_children():
            for subsection in section.get_children():
                for unit in subsection.get_children():
                    for child in unit.get_children():
                        if child.location.category not in PROB_TYPE_LIST:
                            continue

                        problem_id = child.location
                        problem = client.modules(course_id, problem_id)

                        try:
                            grade_distribution = problem.grade_distribution()
                        except NotFoundError:
                            grade_distribution = []

                        for score in grade_distribution:
                            total_student_count[problem_id] += score['count']

                            if problem_id in prob_grade_distrib:
                                if prob_grade_distrib[problem_id][
                                        'max_grade'] < score['max_grade']:
                                    prob_grade_distrib[problem_id][
                                        'max_grade'] = score['max_grade']

                                prob_grade_distrib[problem_id][
                                    'grade_distrib'].append(
                                        (score['grade'], score['count']))
                            else:
                                prob_grade_distrib[problem_id] = {
                                    'max_grade':
                                    score['max_grade'],
                                    'grade_distrib': [
                                        (score['grade'], score['count']),
                                    ],
                                }

    return prob_grade_distrib, total_student_count
Пример #4
0
def get_problem_set_grade_distrib(course_id, problem_set, enrollment):
    """
    Returns the grade distribution for the problems specified in `problem_set`.

    `course_id` the course ID for the course interested in

    `problem_set` an array of UsageKeys representing problem module_id's.

    `enrollment` the number of students enrolled in this course.

    Requests from the database the a count of each grade for each problem in the `problem_set`.

    Returns a dict, where the key is the problem 'module_id' and the value is a dict with two parts:
      'max_grade' - the maximum grade possible for the course
      'grade_distrib' - array of tuples (`grade`,`count`) ordered by `grade`
    """

    non_student_list = get_non_student_list(course_id)

    prob_grade_distrib = {}

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for grade data for set of problems in course
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            grade__isnull=False,
            module_type__in=PROB_TYPE_LIST,
            module_state_key__in=problem_set,
        ).exclude(student_id__in=non_student_list).values(
            'module_state_key',
            'grade',
            'max_grade',
        ).annotate(count_grade=Count('grade')).order_by(
            'module_state_key', 'grade')

        # Loop through resultset building data for each problem
        for row in queryset:
            problem_id = course_id.make_usage_key_from_deprecated_string(
                row['module_state_key'])
            if problem_id not in prob_grade_distrib:
                prob_grade_distrib[problem_id] = {
                    'max_grade': 0,
                    'grade_distrib': [],
                }

            curr_grade_distrib = prob_grade_distrib[problem_id]
            curr_grade_distrib['grade_distrib'].append(
                (row['grade'], row['count_grade']))

            if curr_grade_distrib['max_grade'] < row['max_grade']:
                curr_grade_distrib['max_grade'] = row['max_grade']
    else:
        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL,
                        auth_token=settings.ANALYTICS_DATA_TOKEN)

        for problem in problem_set:
            module = client.modules(course_id, problem)

            try:
                grade_distribution = module.grade_distribution()
            except NotFoundError:
                grade_distribution = []

            for score in grade_distribution:
                if problem in prob_grade_distrib:
                    if prob_grade_distrib[problem]['max_grade'] < score[
                            'max_grade']:
                        prob_grade_distrib[problem]['max_grade'] = score[
                            'max_grade']

                    prob_grade_distrib[problem]['grade_distrib'].append(
                        (score['grade'], score['count']))
                else:
                    prob_grade_distrib[problem] = {
                        'max_grade': score['max_grade'],
                        'grade_distrib': [(score['grade'], score['count'])],
                    }

    return prob_grade_distrib
Пример #5
0
def get_problem_grade_distribution(course_id, enrollment):
    """
    Returns the grade distribution per problem for the course

    `course_id` the course ID for the course interested in

    `enrollment` the number of students enrolled in this course.

    Output is 2 dicts:
      'prob-grade_distrib' where the key is the problem 'module_id' and the value is a dict with:
        'max_grade' - max grade for this problem
        'grade_distrib' - array of tuples (`grade`,`count`).
      'total_student_count' where the key is problem 'module_id' and the value is number of students
        attempting the problem
    """
    non_student_list = get_non_student_list(course_id)

    prob_grade_distrib = {}
    total_student_count = defaultdict(int)

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for grade data for all problems in course
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            grade__isnull=False,
            module_type__in=PROB_TYPE_LIST,
        ).exclude(student_id__in=non_student_list).values('module_state_key', 'grade', 'max_grade').annotate(count_grade=Count('grade'))

        # Loop through resultset building data for each problem
        for row in queryset:
            curr_problem = course_id.make_usage_key_from_deprecated_string(row['module_state_key'])

            # Build set of grade distributions for each problem that has student responses
            if curr_problem in prob_grade_distrib:
                prob_grade_distrib[curr_problem]['grade_distrib'].append((row['grade'], row['count_grade']))

                if ((prob_grade_distrib[curr_problem]['max_grade'] != row['max_grade']) and
                        (prob_grade_distrib[curr_problem]['max_grade'] < row['max_grade'])):
                    prob_grade_distrib[curr_problem]['max_grade'] = row['max_grade']

            else:
                prob_grade_distrib[curr_problem] = {
                    'max_grade': row['max_grade'],
                    'grade_distrib': [(row['grade'], row['count_grade']), ],
                }

            # Build set of total students attempting each problem
            total_student_count[curr_problem] += row['count_grade']
    else:
        # Retrieve course object down to problems
        course = modulestore().get_course(course_id, depth=4)

        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL, auth_token=settings.ANALYTICS_DATA_TOKEN)

        for section in course.get_children():
            for subsection in section.get_children():
                for unit in subsection.get_children():
                    for child in unit.get_children():
                        if child.location.category not in PROB_TYPE_LIST:
                            continue

                        problem_id = child.location
                        problem = client.modules(course_id, problem_id)

                        try:
                            grade_distribution = problem.grade_distribution()
                        except NotFoundError:
                            grade_distribution = []

                        for score in grade_distribution:
                            total_student_count[problem_id] += score['count']

                            if problem_id in prob_grade_distrib:
                                if prob_grade_distrib[problem_id]['max_grade'] < score['max_grade']:
                                    prob_grade_distrib[problem_id]['max_grade'] = score['max_grade']

                                prob_grade_distrib[problem_id]['grade_distrib'].append((score['grade'], score['count']))
                            else:
                                prob_grade_distrib[problem_id] = {
                                    'max_grade': score['max_grade'],
                                    'grade_distrib': [(score['grade'], score['count']), ],
                                }

    return prob_grade_distrib, total_student_count
Пример #6
0
def get_problem_set_grade_distrib(course_id, problem_set, enrollment):
    """
    Returns the grade distribution for the problems specified in `problem_set`.

    `course_id` the course ID for the course interested in

    `problem_set` an array of UsageKeys representing problem module_id's.

    `enrollment` the number of students enrolled in this course.

    Requests from the database the a count of each grade for each problem in the `problem_set`.

    Returns a dict, where the key is the problem 'module_id' and the value is a dict with two parts:
      'max_grade' - the maximum grade possible for the course
      'grade_distrib' - array of tuples (`grade`,`count`) ordered by `grade`
    """

    non_student_list = get_non_student_list(course_id)

    prob_grade_distrib = {}

    if enrollment <= settings.MAX_ENROLLEES_FOR_METRICS_USING_DB or not settings.ANALYTICS_DATA_URL:
        # Aggregate query on studentmodule table for grade data for set of problems in course
        queryset = models.StudentModule.objects.filter(
            course_id__exact=course_id,
            grade__isnull=False,
            module_type__in=PROB_TYPE_LIST,
            module_state_key__in=problem_set,
        ).exclude(student_id__in=non_student_list).values(
            'module_state_key',
            'grade',
            'max_grade',
        ).annotate(count_grade=Count('grade')).order_by('module_state_key', 'grade')

        # Loop through resultset building data for each problem
        for row in queryset:
            problem_id = course_id.make_usage_key_from_deprecated_string(row['module_state_key'])
            if problem_id not in prob_grade_distrib:
                prob_grade_distrib[problem_id] = {
                    'max_grade': 0,
                    'grade_distrib': [],
                }

            curr_grade_distrib = prob_grade_distrib[problem_id]
            curr_grade_distrib['grade_distrib'].append((row['grade'], row['count_grade']))

            if curr_grade_distrib['max_grade'] < row['max_grade']:
                curr_grade_distrib['max_grade'] = row['max_grade']
    else:
        # Connect to analytics data client
        client = Client(base_url=settings.ANALYTICS_DATA_URL, auth_token=settings.ANALYTICS_DATA_TOKEN)

        for problem in problem_set:
            module = client.modules(course_id, problem)

            try:
                grade_distribution = module.grade_distribution()
            except NotFoundError:
                grade_distribution = []

            for score in grade_distribution:
                if problem in prob_grade_distrib:
                    if prob_grade_distrib[problem]['max_grade'] < score['max_grade']:
                        prob_grade_distrib[problem]['max_grade'] = score['max_grade']

                    prob_grade_distrib[problem]['grade_distrib'].append((score['grade'], score['count']))
                else:
                    prob_grade_distrib[problem] = {
                        'max_grade': score['max_grade'],
                        'grade_distrib': [(score['grade'], score['count'])],
                    }

    return prob_grade_distrib