def gen_quiz_summary_report(ready_course, ready_quiz, save_to_s3=False):
    
    ### 1- Create the S3 file name and report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    is_video = isinstance(ready_quiz, Video)
    is_summative = (not is_video) and (ready_quiz.assessment_type == 'assessive')
    
    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, ready_quiz.slug)
    if is_video:
        s3_filepath = "%s/%s/reports/videos_summary/%s" % (course_prefix, course_suffix, report_name)
    else:
        s3_filepath = "%s/%s/reports/problemsets_summary/%s" % (course_prefix, course_suffix, report_name)
    
    rw = C2GReportWriter(save_to_s3, s3_filepath)
    
    ### 2- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz)
    per_student_data = quiz_data['per_student_data']
    exercise_summaries = quiz_data['exercise_summaries']
    
    ### 4- Write out the report content
    WriteQuizSummaryReportContent(ready_quiz, rw, full=False)

    ### 5- Proceed to write out and return
    report_content = rw.writeout()
    return {'name': report_name, 'content': report_content, 'path': s3_filepath}
Exemplo n.º 2
0
def gen_quiz_summary_report(ready_course, ready_quiz, save_to_s3=False):
    
    ### 1- Create the S3 file name and report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    is_video = isinstance(ready_quiz, Video)
    is_summative = (not is_video) and (ready_quiz.assessment_type == 'assessive')
    
    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, ready_quiz.slug)
    if is_video:
        s3_filepath = "%s/%s/reports/videos_summary/%s" % (course_prefix, course_suffix, report_name)
    else:
        s3_filepath = "%s/%s/reports/problemsets_summary/%s" % (course_prefix, course_suffix, report_name)
    
    rw = C2GReportWriter(save_to_s3, s3_filepath)
    
    ### 2- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz)
    per_student_data = quiz_data['per_student_data']
    exercise_summaries = quiz_data['exercise_summaries']
    
    ### 4- Write out the report content
    WriteQuizSummaryReportContent(ready_quiz, rw, full=False)

    ### 5- Proceed to write out and return
    report_content = rw.writeout()
    return {'name': report_name, 'content': report_content, 'path': s3_filepath}
def WriteQuizSummaryReportContent(ready_quiz, rw, full=False):
    ### 1- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz)
    quiz_summary = quiz_data['quiz_summary']
    exercise_summaries = quiz_data['exercise_summaries']
    
    ### 2- Write the title line
    rw.write([quiz_summary['title']])
    
    ### 3- Write out per-exercise report content
    if len(exercise_summaries) == 0:
        rw.write(content = ["No exercises have been added yet."], indent = 1, nl = 1)
        return
    
    # Summative problem sets get their mean and max scores written in the report
    if quiz_summary['assessment_type'] == 'summative':
        if len(quiz_summary['scores']) > 0:
            rw.write([
                "Mean score", mean(quiz_summary['scores']),
                "Max score", max(quiz_summary['scores']),
                "",
                "Mean score after late penalty", mean(quiz_summary['scores_after_late_penalty']),
                "Max score after late penalty", max(quiz_summary['scores_after_late_penalty']),
            ], indent = 1, nl = 1)
        
    # Exercise summary table header
    content = ["Exercise"]
    if quiz_summary['assessment_type'] == 'summative': content.extend(["Mean score", "Max score"])
    content.extend([
        "Total attempts",
        "Students who have attempted",
        "Correct attempts",
        "Correct 1st attempts",
        "Correct 2nd attempts",
        "Correct 3rd attempts",
        "Median attempts to (and including) first correct attempt",
        "Median attempt time",
        "Most freq incorrect answer",
    ])
    rw.write(content, indent = 1)
    
    # Exercise summary table rows
    for ex_summary in exercise_summaries:
        content = [ex_summary['slug']]
        if quiz_summary['assessment_type'] == 'summative':
            if len(ex_summary['scores']) > 0:
                content.extend([mean(ex_summary['scores']), max(ex_summary['scores'])])
            else:
                content.extend(["", ""])
        
        most_freq_inc_ans_str = "Too few, or no high freq, incorrect attempts"
        if len(ex_summary['most_frequent_incorrect_answers']) > 0:
            most_freq_inc_ans_content = ex_summary['most_frequent_incorrect_answers'][0][0]
            most_freq_inc_ans_percent = ex_summary['most_frequent_incorrect_answers'][0][1]
            most_freq_inc_ans_str = "%s (%.2f%% of all incorrect attempts)" % (most_freq_inc_ans_content, most_freq_inc_ans_percent)
            
        content.extend([
            ex_summary['num_attempts'],
            ex_summary['num_attempting_students'],
            ex_summary['num_correct_attempts'],
            ex_summary['num_correct_first_attempts'],
            ex_summary['num_correct_second_attempts'],
            ex_summary['num_correct_third_attempts'],
            ex_summary['median_num_attempts_to_fca'],
            ex_summary['median_attempt_time'],
            json.dumps(most_freq_inc_ans_str),
        ])
        
        rw.write(content, indent = 1)
        
    rw.write([""])
Exemplo n.º 4
0
def WriteQuizSummaryReportContent(ready_quiz, rw, full=False):
    ### 1- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz)
    quiz_summary = quiz_data['quiz_summary']
    exercise_summaries = quiz_data['exercise_summaries']
    
    ### 2- Write the title line
    rw.write([quiz_summary['title']])
    
    ### 3- Write out per-exercise report content
    if len(exercise_summaries) == 0:
        rw.write(content = ["No exercises have been added yet."], indent = 1, nl = 1)
        return
    
    # Summative problem sets get their mean and max scores written in the report
    if quiz_summary['assessment_type'] == 'summative':
        if len(quiz_summary['scores']) > 0:
            rw.write([
                "Mean score", mean(quiz_summary['scores']),
                "Max score", max(quiz_summary['scores']),
                "",
                "Mean score after late penalty", mean(quiz_summary['scores_after_late_penalty']),
                "Max score after late penalty", max(quiz_summary['scores_after_late_penalty']),
            ], indent = 1, nl = 1)
        
    # Exercise summary table header
    content = ["Exercise"]
    if quiz_summary['assessment_type'] == 'summative': content.extend(["Mean score", "Max score"])
    content.extend([
        "Total attempts",
        "Students who have attempted",
        "Correct attempts",
        "Correct 1st attempts",
        "Correct 2nd attempts",
        "Correct 3rd attempts",
        "Median attempts to (and including) first correct attempt",
        "Median attempt time",
        "Most freq incorrect answer",
    ])
    rw.write(content, indent = 1)
    
    # Exercise summary table rows
    for ex_summary in exercise_summaries:
        content = [ex_summary['slug']]
        if quiz_summary['assessment_type'] == 'summative':
            if len(ex_summary['scores']) > 0:
                content.extend([mean(ex_summary['scores']), max(ex_summary['scores'])])
            else:
                content.extend(["", ""])
        
        most_freq_inc_ans_str = "Too few, or no high freq, incorrect attempts"
        if len(ex_summary['most_frequent_incorrect_answers']) > 0:
            most_freq_inc_ans_content = ex_summary['most_frequent_incorrect_answers'][0][0]
            most_freq_inc_ans_percent = ex_summary['most_frequent_incorrect_answers'][0][1]
            most_freq_inc_ans_str = "%s (%.2f%% of all incorrect attempts)" % (most_freq_inc_ans_content, most_freq_inc_ans_percent)
            
        content.extend([
            ex_summary['num_attempts'],
            ex_summary['num_attempting_students'],
            ex_summary['num_correct_attempts'],
            ex_summary['num_correct_first_attempts'],
            ex_summary['num_correct_second_attempts'],
            ex_summary['num_correct_third_attempts'],
            ex_summary['median_num_attempts_to_fca'],
            ex_summary['median_attempt_time'],
            json.dumps(most_freq_inc_ans_str),
        ])
        
        rw.write(content, indent = 1)
        
    rw.write([""])
Exemplo n.º 5
0
def gen_quiz_full_report(ready_course, ready_quiz, save_to_s3=False):

    ### 1- Create the S3 file name and report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    is_video = isinstance(ready_quiz, Video)
    is_summative = (not is_video) and (ready_quiz.assessment_type == 'assessive')
    
    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, ready_quiz.slug)
    if is_video:
        s3_filepath = "%s/%s/reports/videos/%s" % (course_prefix, course_suffix, report_name)
    else:
        s3_filepath = "%s/%s/reports/problemsets/%s" % (course_prefix, course_suffix, report_name)
    
    rw = C2GReportWriter(save_to_s3, s3_filepath)
    
    ### 2- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz, get_visits = True)
    per_student_data = quiz_data['per_student_data']
    exercise_summaries = quiz_data['exercise_summaries']
    ex_ids = [ex_summ['id'] for ex_summ in exercise_summaries]
    
    ### 3- Writeout
    rw.write(["Activity for %s" % quiz_data['quiz_summary']['title']], nl = 1) 

    # Sort students by username
    sorted_usernames = sorted(per_student_data.keys())
    
    # If no activity, do not type anything unneeded.
    if not has_activity(per_student_data):
        rw.write(content=["No activity yet."], indent=1)
        report_content = rw.writeout()
        return {'name': report_name, 'path': s3_filepath, 'content': report_content}
        
    header1 = ["", ""]
    header2 = ["", ""]
    
    header1.extend(["", "Total score / %d"  % len(exercise_summaries)])
    header2.extend(["", ""])
    if is_summative:
        header1.extend(["Total score after late penalty"])
        header2.extend([""])
    
    header1.extend(["", "Num page visits", "Visit date/times"])
    header2.extend(["", "", ""])
        
    for ex_summary in exercise_summaries:
        header1.extend(["", "", ex_summary['slug'], "", "", ""])
        header2.extend(["", "", "Completed", "Attempts", "Score", "Median attempt time"])
        if is_summative:
            header1.extend(["",""])
            header2.extend(["First correct attempt timestamp", "Score after late penalty"])
    
    rw.write(header1)
    rw.write(header2)
    
    for u in sorted_usernames:
        stud_quiz_data = per_student_data[u]
        
        if len(stud_quiz_data['visits']) == 0 and len(stud_quiz_data['exercise_activity']) == 0:
            continue
        
        stud_score = 0
        stud_score_after_late_penalty = 0
        
        # User- and full name
        content = [u, stud_quiz_data['name']]
        
        # Total scores
        for ex_id in ex_ids:
            if ex_id in stud_quiz_data['exercise_activity']:
                ex_res = stud_quiz_data['exercise_activity'][ex_id]
            
                stud_score += (ex_res['score'] if isinstance(ex_res['score'], float) else 0)
                if is_summative and isinstance(ex_res['score_after_late_penalty'], float):
                    stud_score_after_late_penalty += ex_res['score_after_late_penalty']
        
        content.extend(["", stud_score])
        if is_summative:
            content.append(stud_score_after_late_penalty)
            
        
        # Student visit data
        content.extend(["", len(stud_quiz_data['visits']), ", ".join(stud_quiz_data['visits']) ])
        
        for ex_id in ex_ids:
            if ex_id in stud_quiz_data['exercise_activity']: ex_res = stud_quiz_data['exercise_activity'][ex_id]
            else: ex_res = {'completed': '', 'attempts': '', 'score': '', 'last_attempt_timestamp': '', 'score_after_late_penalty': '', 'median_attempt_time': ''}
            
            content.extend(["", "", 'y' if ex_res['completed'] else 'n', ex_res['attempts'], ex_res['score'], ex_res['median_attempt_time']])
            if is_summative:
                first_correct_attempt_timestamp = get_friendly_datetime(ex_res['last_attempt_timestamp']) if ex_res['completed'] else ""
                content.extend([first_correct_attempt_timestamp, ex_res['score_after_late_penalty']])
            
        rw.write(content)
        
    report_content = rw.writeout()
    return {'name': report_name, 'content': report_content, 'path': s3_filepath}
Exemplo n.º 6
0
def gen_quiz_full_report(ready_course, ready_quiz, save_to_s3=False):

    ### 1- Create the S3 file name and report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    is_video = isinstance(ready_quiz, Video)
    is_summative = (not is_video) and (ready_quiz.assessment_type
                                       == 'assessive')

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
        ready_quiz.slug)
    if is_video:
        s3_filepath = "%s/%s/reports/videos/%s" % (course_prefix,
                                                   course_suffix, report_name)
    else:
        s3_filepath = "%s/%s/reports/problemsets/%s" % (
            course_prefix, course_suffix, report_name)

    rw = C2GReportWriter(save_to_s3, s3_filepath)

    ### 2- Get the quiz data
    quiz_data = get_quiz_data(ready_quiz, get_visits=True)
    per_student_data = quiz_data['per_student_data']
    exercise_summaries = quiz_data['exercise_summaries']
    ex_ids = [ex_summ['id'] for ex_summ in exercise_summaries]

    ### 3- Writeout
    rw.write(["Activity for %s" % quiz_data['quiz_summary']['title']], nl=1)

    # Sort students by username
    sorted_usernames = sorted(per_student_data.keys())

    # If no activity, do not type anything unneeded.
    if not has_activity(per_student_data):
        rw.write(content=["No activity yet."], indent=1)
        report_content = rw.writeout()
        return {
            'name': report_name,
            'path': s3_filepath,
            'content': report_content
        }

    header1 = ["", ""]
    header2 = ["", ""]

    header1.extend(["", "Total score / %d" % len(exercise_summaries)])
    header2.extend(["", ""])
    if is_summative:
        header1.extend(["Total score after late penalty"])
        header2.extend([""])

    header1.extend(["", "Num page visits", "Visit date/times"])
    header2.extend(["", "", ""])

    for ex_summary in exercise_summaries:
        header1.extend(["", "", ex_summary['slug'], "", "", ""])
        header2.extend(
            ["", "", "Completed", "Attempts", "Score", "Median attempt time"])
        if is_summative:
            header1.extend(["", ""])
            header2.extend([
                "First correct attempt timestamp", "Score after late penalty"
            ])

    rw.write(header1)
    rw.write(header2)

    for u in sorted_usernames:
        stud_quiz_data = per_student_data[u]

        if len(stud_quiz_data['visits']) == 0 and len(
                stud_quiz_data['exercise_activity']) == 0:
            continue

        stud_score = 0
        stud_score_after_late_penalty = 0

        # User- and full name
        content = [u, stud_quiz_data['name']]

        # Total scores
        for ex_id in ex_ids:
            if ex_id in stud_quiz_data['exercise_activity']:
                ex_res = stud_quiz_data['exercise_activity'][ex_id]

                stud_score += (ex_res['score'] if isinstance(
                    ex_res['score'], float) else 0)
                if is_summative and isinstance(
                        ex_res['score_after_late_penalty'], float):
                    stud_score_after_late_penalty += ex_res[
                        'score_after_late_penalty']

        content.extend(["", stud_score])
        if is_summative:
            content.append(stud_score_after_late_penalty)

        # Student visit data
        content.extend([
            "",
            len(stud_quiz_data['visits']), ", ".join(stud_quiz_data['visits'])
        ])

        for ex_id in ex_ids:
            if ex_id in stud_quiz_data['exercise_activity']:
                ex_res = stud_quiz_data['exercise_activity'][ex_id]
            else:
                ex_res = {
                    'completed': '',
                    'attempts': '',
                    'score': '',
                    'last_attempt_timestamp': '',
                    'score_after_late_penalty': '',
                    'median_attempt_time': ''
                }

            content.extend([
                "", "", 'y' if ex_res['completed'] else 'n',
                ex_res['attempts'], ex_res['score'],
                ex_res['median_attempt_time']
            ])
            if is_summative:
                first_correct_attempt_timestamp = get_friendly_datetime(
                    ex_res['last_attempt_timestamp']
                ) if ex_res['completed'] else ""
                content.extend([
                    first_correct_attempt_timestamp,
                    ex_res['score_after_late_penalty']
                ])

        rw.write(content)

    report_content = rw.writeout()
    return {
        'name': report_name,
        'content': report_content,
        'path': s3_filepath
    }