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([""])
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}
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 }