Exemple #1
0
def gen_course_quizzes_report(ready_course, save_to_s3=False):
    
    ### 1- Compose the report file name and instantiate the report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    
    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s-Course-Quizzes.csv" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, course_prefix+'_'+course_suffix)
    s3_filepath = "%s/%s/reports/course_quizzes/%s" % (course_prefix, course_suffix, report_name)
    
    rw = C2GReportWriter(save_to_s3, s3_filepath)
    
    ### 2- Write the Report Title
    rw.write(content = ["Course Quiz Summaries for %s (%s %d)" % (ready_course.title, ready_course.term.title(), ready_course.year)], nl = 1)
    
    ### 3- Write problem set reports
    rw.write(content = ["Problem sets"], nl = 1)
    
    problemsets = ProblemSet.objects.getByCourse(course=ready_course).order_by('section__index', 'index')
    for q in problemsets:
        WriteQuizSummaryReportContent(q, rw, full=False)
    
    ### 4- Write video reports
    rw.write(content = ["Videos"], nl = 1)
    
    videos = Video.objects.getByCourse(course=ready_course).order_by('section__index', 'index')
    for q in videos:
        WriteQuizSummaryReportContent(q, 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 gen_course_quizzes_report(ready_course, save_to_s3=False):
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    s3_filepath = "%s/%s/reports/course_quizzes/daily/%02d_%02d_%02d__%02d_%02d_%02d-%s-Course-Quizzes.csv" % (
        course_prefix, course_suffix, dt.year, dt.month, dt.day, dt.hour,
        dt.minute, dt.second, course_prefix + '_' + course_suffix)

    rw = C2GReportWriter(ready_course, save_to_s3, s3_filepath)

    # Title
    rw.write(content=[
        "Course Quizzes for %s (%s %d)" %
        (ready_course.title, ready_course.term.title(), ready_course.year)
    ],
             nl=1)

    # Get a list of Quizzes (Problem sets and videos with exercises)
    quizzes = []
    problemsets = ProblemSet.objects.getByCourse(course=ready_course)
    for ps in problemsets:
        quizzes.append(ps)

    videos = Video.objects.getByCourse(course=ready_course)
    for vd in videos:
        quizzes.append(vd)

    quizzes = sorted(quizzes, key=lambda k: k.live_datetime, reverse=True)

    for q in quizzes:
        WriteQuizDataToReport(q, rw)

    rw.close()
def gen_assessment_student_scores_report(ready_course, save_to_s3=False):

    ### 1- Compose the report file name and instantiate the report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second)
    s3_filepath = "%s/%s/reports/assessment_student_scores/%s" % (
        course_prefix, course_suffix, report_name)

    rw = C2GReportWriter(save_to_s3, s3_filepath)

    ### 2- Write the Report Title
    rw.write(content=[
        "Student Scores for %s (%s %d)" %
        (ready_course.title, ready_course.term.title(), ready_course.year)
    ],
             nl=1)
    rw.write(
        content=["All student scores shown are with all penalties included"])

    ### 3- Write survey report
    WriteAssessmentStudentScoresReportContent(ready_course, rw, full=False)

    ### 4- Proceed to write out and return
    report_content = rw.writeout()
    return {
        'name': report_name,
        'content': report_content,
        'path': s3_filepath
    }
Exemple #4
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 gen_survey_summary_report(ready_course, survey, save_to_s3=False):

    ### 1- Compose the report file name and instantiate the report writer object
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, survey.slug)
    s3_filepath = "%s/%s/reports/survey_summary/%s" % (
        course_prefix, course_suffix, report_name)

    rw = C2GReportWriter(save_to_s3, s3_filepath)

    ### 2- Write the Report Title
    rw.write(content=[
        "Survey Summary for %s (%s %d)" %
        (ready_course.title, ready_course.term.title(), ready_course.year)
    ],
             nl=1)

    ### 3- Write survey report
    WriteSurveySummaryReportContent(survey, rw, full=False)

    ### 4- Proceed to write out and return
    report_content = rw.writeout()
    return {
        'name': report_name,
        'content': report_content,
        'path': s3_filepath
    }
def gen_class_roster(ready_course, save_to_s3=False):
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s-Class-Roster.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
        course_prefix + '_' + course_suffix)
    s3_filepath = "%s/%s/reports/class_roster/%s" % (
        course_prefix, course_suffix, report_name)

    rw = C2GReportWriter(save_to_s3, s3_filepath)

    # Title
    rw.write(content=[
        "Class Roster for %s (%s %d) as of %02d/%02d/%d" %
        (ready_course.title, ready_course.term.title(), ready_course.year,
         dt.month, dt.day, dt.year)
    ],
             nl=1)

    # Members
    students = ready_course.student_group.user_set.order_by(
        'username').all().order_by('last_name').values_list(
            'first_name', 'last_name', 'email', 'username')

    rw.write(content=["Num. Students:", "", len(students)], nl=1)

    rw.write(content=["First namme", "Last name", "Email", "Username"])
    for s in students:
        rw.write(content=[s[0], s[1], s[2], s[3]])

    report_content = rw.writeout()
    return {
        'name':
        "%02d_%02d_%02d__%02d_%02d_%02d-%s-Class-Roster.csv" %
        (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
         course_prefix + '_' + course_suffix),
        'content':
        report_content,
        'path':
        s3_filepath
    }
Exemple #7
0
def gen_quiz_data_report(ready_course, ready_quiz, save_to_s3=False):
    students_ = ready_course.student_group.user_set.all().values_list(
        'id', 'username', 'first_name', 'last_name')
    students = {}
    for s in students_:
        students[s[0]] = {"username": s[1], "name": "%s %s" % (s[2], s[3])}

    mean = lambda k: sum(k) / len(k)
    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')
    is_formative = (is_video) or (ready_quiz.assessment_type == 'formative')

    if is_summative:
        submissions_permitted = ready_quiz.submissions_permitted
        if submissions_permitted == 0: submissions_permitted = 100000
        resubmission_penalty = ready_quiz.resubmission_penalty / 100.0
        grace_deadline = ready_quiz.grace_period
        if not grace_deadline: grace_deadline = ready_quiz.due_date
        partial_credit_deadline = ready_quiz.partial_credit_deadline
        late_penalty = ready_quiz.late_penalty / 100.0

    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)
    rw.write([
        "Activity for %s \"%s\" in %s (%s %d)" %
        ('Video' if is_video else 'Problem Set', ready_quiz.title,
         ready_course.title, ready_course.term.title(), ready_course.year)
    ],
             nl=1)

    data = {}

    if is_video:
        rlns = VideoToExercise.objects.filter(
            video=ready_quiz, is_deleted=0).order_by('video_time')
    else:
        rlns = ProblemSetToExercise.objects.filter(
            problemSet=ready_quiz, is_deleted=0).order_by('number')

    if is_video:
        video_visits = PageVisitLog.objects.filter(
            page_type='video',
            object_id=str(ready_quiz.id)).order_by('user', 'time_created')
        for vv in video_visits:
            if not vv.user.username in data:
                stud_username = vv.user.username
                stud_fullname = vv.user.first_name + " " + vv.user.last_name
                data[vv.user.username] = {
                    'username': stud_username,
                    'name': stud_fullname,
                    'visits': []
                }
            data[vv.user.username]['visits'].append(
                "%s-%s-%s at %s:%s" %
                (vv.time_created.year, vv.time_created.month,
                 vv.time_created.day, vv.time_created.hour,
                 vv.time_created.minute))

    ex_ids = []
    for rln in rlns:
        ex = rln.exercise
        ex_ids.append(ex.id)

        if is_video:
            atts = ProblemActivity.objects.select_related(
                'video', 'exercise').filter(
                    video_to_exercise__exercise__fileName=ex.fileName,
                    video_to_exercise__video=ready_quiz).order_by(
                        'student',
                        'time_created').values_list('student_id', 'complete',
                                                    'time_taken',
                                                    'attempt_content',
                                                    'time_created')
        else:
            atts = ProblemActivity.objects.select_related(
                'problemSet', 'exercise').filter(
                    problemset_to_exercise__exercise__fileName=ex.fileName,
                    problemset_to_exercise__problemSet=ready_quiz).order_by(
                        'student',
                        'time_created').values_list('student_id', 'complete',
                                                    'time_taken',
                                                    'attempt_content',
                                                    'time_created')

        submitters = [item[0] for item in atts]
        completes = [item[1] for item in atts]
        times_taken = [item[2] for item in atts]
        attempts_content = [item[3] for item in atts]
        times_created = [item[4] for item in atts]

        for i in range(0, len(atts)):
            if not (submitters[i] in students):
                continue  # Do not include attempts by non-students in the report

            is_student_first_attempt = (i == 0) or (submitters[i] !=
                                                    submitters[i - 1])
            is_student_last_attempt = (i == len(atts) - 1) or (
                submitters[i] != submitters[i + 1])

            if is_student_first_attempt:
                stud_username = students[submitters[i]]['username']
                if not stud_username in data:
                    stud_fullname = students[submitters[i]]['name']
                    data[stud_username] = {
                        'username': stud_username,
                        'name': stud_fullname,
                        'visits': []
                    }
                attempt_number = 0
                completed = False
                attempt_times = []
                attempts = []
                num_incorrect_attempts = 0

            if not completed:
                attempt_number += 1
                attempt_times.append(times_taken[i])
                attempts.append(attempts_content[i].replace("\r", "").replace(
                    "\n", ";"))

            if completes[i] == 1:
                completed = True
                num_incorrect_attempts = attempt_number - 1
                first_correct_attempt_time_created = times_created[i]

            if is_student_last_attempt:
                score = 0
                score_after_late_penalty = 0
                if is_summative:
                    if completed and (num_incorrect_attempts + 1 <=
                                      submissions_permitted):
                        score = 1.0 - (
                            num_incorrect_attempts) * resubmission_penalty
                        score_after_late_penalty = score

                    # Apply late penalty if necessary
                    if first_correct_attempt_time_created > partial_credit_deadline:
                        if partial_credit_deadline:
                            score_after_late_penalty = 0

                    elif first_correct_attempt_time_created > grace_deadline:
                        if grace_deadline:
                            score_after_late_penalty = score * (1 -
                                                                late_penalty)

                    if score < 0: score = 0
                    if score_after_late_penalty < 0:
                        score_after_late_penalty = 0

                elif is_formative:
                    if completed: score = 1.0
                    else: score = 0.0

                data[stud_username][ex.id] = {
                    'completed': 'y' if completed else 'n',
                    'attempts': json.dumps(attempts),
                    'median_attempt_time': median(attempt_times),
                    'score': score
                }
                if is_summative:
                    data[stud_username][ex.id][
                        'score_after_late_penalty'] = score_after_late_penalty

    ##### Start Write Out #####

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

    # If not activity, do not type anything unneeded.
    if len(sorted_usernames) == 0:
        rw.write(content=[
            "No activity yet for this %s" %
            ('video' if is_video else 'problem set')
        ],
                 indent=1)
        report_content = rw.writeout()
        return {
            'name': report_name,
            'path': s3_filepath,
            'content': report_content
        }

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

    if is_video:
        header1.extend(["", "", "Num video visits", "Visits date/times"])
        header2.extend(["", "", "", ""])

    for rln in rlns:
        header1.extend(["", "", rln.exercise.get_slug(), "", "", ""])
        header2.extend(
            ["", "", "Completed", "Attempts", "Median attempt time", "Score"])
        if is_summative:
            header1.append("")
            header2.append("Score after Late Penalty")

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

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

    for u in sorted_usernames:
        r = data[u]
        stud_score = 0
        stud_score_after_late_penalty = 0

        content = [u, r['name']]
        if is_video:
            visit_dt_string = ""
            for vvi in range(len(data[u]['visits'])):
                if vvi > 0: visit_dt_string += ', '
                visit_dt_string += data[u]['visits'][vvi]

            content.extend(["", "", len(data[u]['visits']), visit_dt_string])

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

            content.extend([
                "", "", ex_res['completed'], ex_res['attempts'],
                ex_res['median_attempt_time'], ex_res['score']
            ])
            if is_summative: content.append(ex_res['score_after_late_penalty'])

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

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

        rw.write(content)

    report_content = rw.writeout()
    return {
        'name': report_name,
        'content': report_content,
        'path': s3_filepath
    }
Exemple #8
0
def gen_course_dashboard_report(ready_course, save_to_s3=False):
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    s3_filepath = "%s/%s/reports/dashboard/%02d_%02d_%02d__%02d_%02d_%02d-%s-Dashboard.csv" % (course_prefix, course_suffix, dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, course_prefix+'_'+course_suffix)
    
    rw = C2GReportWriter(ready_course, save_to_s3, s3_filepath)
    
    # Title
    rw.write(content = ["Dashboard for %s (%s %d)" % (ready_course.title, ready_course.term.title(), ready_course.year)], nl = 1)
    
    # Members
    num_prof = ready_course.instructor_group.user_set.all().count()
    num_stud = ready_course.student_group.user_set.all().count()
    num_tas = ready_course.tas_group.user_set.all().count()
    num_rota = ready_course.readonly_tas_group.user_set.all().count()
    
    rw.write(content = ["Members"])
    rw.write(content = ["Students", num_stud, "Professors", num_prof, "TAs", num_tas, "Readonly TAs", num_rota], indent = 1, nl = 1)
    
    # Content
    problem_sets = ProblemSet.objects.getByCourse(course=ready_course).order_by('-live_datetime')
    videos = Video.objects.getByCourse(course=ready_course).order_by('-live_datetime')
    additional_pages = AdditionalPage.objects.getSectionPagesByCourse(course=ready_course).order_by('-live_datetime')
    
    num_all_formative_problem_sets = ProblemSet.objects.getByCourse(course=ready_course.image).filter(assessment_type="formative").count()
    num_live_formative_problem_sets = problem_sets.filter(assessment_type="formative").count()
    num_all_summative_problem_sets = ProblemSet.objects.getByCourse(course=ready_course.image).filter(assessment_type="summative").count()
    num_live_summative_problem_sets = problem_sets.filter(assessment_type="summative").count()
    num_all_videos = Video.objects.getByCourse(course=ready_course.image).count()
    num_live_videos = videos.count()
    num_all_pages = AdditionalPage.objects.getSectionPagesByCourse(course=ready_course.image).count()
    num_live_pages = additional_pages.count()
    num_all_files = File.objects.getByCourse(course=ready_course.image).count()
    num_live_files = File.objects.getByCourse(course=ready_course).count()
    
    rw.write(content = ["Content"])
    rw.write(content = ["Formative problem sets", "Summative Problem sets", "Videos", "Content Pages", "Files"], indent = 2)
    rw.write(content = ["All", num_all_formative_problem_sets, num_all_summative_problem_sets, num_all_videos, num_all_pages, num_all_files], indent = 1)
    rw.write(content = ["Live", num_live_formative_problem_sets, num_live_summative_problem_sets, num_live_videos, num_live_pages, num_live_files], indent = 1, nl = 1)
    
    # Activity
    problem_set_visits = get_visit_information(ready_course, problem_sets, 'problemset')
    video_visits = get_visit_information(ready_course, videos, 'video')
    additional_page_visits = get_visit_information(ready_course, additional_pages, 'additional_page')
    forum_visits = get_visit_information(ready_course, None, 'forum')
    
    rw.write(content = ["Page Visits (Only live items are shown)"], nl = 1)
    
    rw.write(content = ["Forum"], indent = 1)
    rw.write(content = ["", "", "", "Past day total", "Past day unique", "", "Past week total", "Past week unique", "", "all_time_total", "all_time_unique"], indent = 1)
    rw.write(content = ["", "", "", forum_visits[0]['past_day_total'], forum_visits[0]['past_day_unique'], "", forum_visits[0]['past_week_total'], forum_visits[0]['past_week_unique'], "", forum_visits[0]['all_time_total'], forum_visits[0]['all_time_unique']], indent = 1, nl = 1)
    rw.write([""])
    
    rw.write(content = ["Problem sets"], indent = 1)
    if len(problem_set_visits) > 0:
        rw.write(content = ["URL ID", "Title", "", "Past day total", "Past day unique", "", "Past week total", "Past week unique", "", "all_time_total", "all_time_unique"], indent = 1)
        for item in problem_set_visits:
            rw.write(content = [item['item'].slug, item['item'].title, "", item['past_day_total'], item['past_day_unique'], "", item['past_week_total'], item['past_week_unique'], "", item['all_time_total'], item['all_time_unique']], indent = 1)
    else:
        rw.write(content = ["No live problem sets yet."], indent = 2)
    rw.write([""])
    
    rw.write(content = ["Videos"], indent = 1)
    if len(video_visits) > 0:
        rw.write(content = ["URL ID", "Title", "", "Past day total", "Past day unique", "", "Past week total", "Past week unique", "", "all_time_total", "all_time_unique"], indent = 1)
        for item in video_visits:
            rw.write(content = [item['item'].slug, item['item'].title, "", item['past_day_total'], item['past_day_unique'], "", item['past_week_total'], item['past_week_unique'], "", item['all_time_total'], item['all_time_unique']], indent = 1)
    else:
        rw.write(content = ["No live videos yet."], indent = 2)
    rw.write([""])
    
    rw.write(content = ["Content pages"], indent = 1)
    if len(additional_page_visits) > 0:
        rw.write(content = ["URL ID", "Title", "", "Past day total", "Past day unique", "", "Past week total", "Past week unique", "", "all_time_total", "all_time_unique"], indent = 1)
        for item in additional_page_visits:
            rw.write(content = [item['item'].slug, item['item'].title, "", item['past_day_total'], item['past_day_unique'], "", item['past_week_total'], item['past_week_unique'], "", item['all_time_total'], item['all_time_unique']], indent = 1)
    else:
        rw.write(content = ["No live content pages yet."], indent = 2)
    rw.write([""])
    
    rw.close()
Exemple #9
0
def gen_quiz_data_report(ready_course, ready_quiz, save_to_s3=False):

    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]
    s3_filepath = "%s/%s/reports/quiz_data/%s/%02d_%02d_%02d__%02d_%02d_%02d-%s-Quiz-Data.csv" % (
        course_prefix, course_suffix, ready_quiz.slug, dt.year, dt.month,
        dt.day, dt.hour, dt.minute, dt.second, ready_quiz.slug)

    rw = C2GReportWriter(ready_course, save_to_s3, s3_filepath)
    rw.write([
        "Quiz Attempts for Quiz \"%s\" in %s (%s %d)" %
        (ready_quiz.title, ready_course.title, ready_course.term.title(),
         ready_course.year)
    ],
             nl=1)

    is_summative = isinstance(
        ready_quiz, ProblemSet) and (ready_quiz.assessment_type == 'summative')

    data = {}
    mean = lambda k: sum(k) / len(k)

    if isinstance(ready_quiz, Video):
        rlns = VideoToExercise.objects.get(
            video=ready_quiz).order_by('video_time')
    else:
        rlns = ProblemSetToExercise.objects.filter(
            problemSet=ready_quiz, ).order_by('number')

    ex_ids = []
    for rln in rlns:
        ex = rln.exercise
        ex_ids.append(ex.id)

        if isinstance(ready_quiz, Video):
            atts = ProblemActivity.objects.filter(
                video_to_exercise=rln).order_by('student', 'time_created')
        else:
            atts = ProblemActivity.objects.filter(
                problemset_to_exercise=rln).order_by('student', 'time_created')

        submitters = atts.values_list('student', flat=True)
        completes = atts.values_list('complete', flat=True)
        times_taken = atts.values_list('time_taken', flat=True)
        attempts_content = atts.values_list('attempt_content', flat=True)

        for i in range(0, len(atts)):
            is_student_first_attempt = (i == 0) or (submitters[i] !=
                                                    submitters[i - 1])
            is_student_last_attempt = (i == len(atts) - 1) or (
                submitters[i] != submitters[i + 1])

            if is_student_first_attempt:
                attempt_number = 0
                stud_username = atts[i].student.username
                stud_fullname = atts[i].student.first_name + " " + atts[
                    i].student.last_name
                completed = False
                attempt_times = []
                attempts = []

            attempt_number += 1

            if not completed:
                attempt_times.append(times_taken[i])
                attempts.append(attempts_content[i])

            if completes[i] == 1: completed = True

            if is_student_last_attempt:
                score = 0
                if is_summative:
                    if (attempt_number +
                            1) <= ready_quiz.submissions_permitted:
                        score = 1 - attempt_number * ready_quiz.resubmission_penalty / 100.0
                    if score < 0: score = 0

                if not stud_username in data:
                    data[stud_username] = {
                        'username': stud_username,
                        'name': stud_fullname
                    }

                data[stud_username][ex.id] = {
                    'completed': 'y' if completed else 'n',
                    'attempts': json.dumps(attempts),
                    'mean_attempt_time': mean(attempt_times)
                }
                if is_summative: data[stud_username][ex.id]['score'] = score

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

    header1 = ["", ""]
    header2 = ["", ""]
    for rln in rlns:
        header1.extend(["", "", rln.exercise.get_slug(), "", "", ""])
        header2.extend(["", "", "Completed", "attemps"])
        if is_summative: header2.append("Score")
        header2.append("Mean attempt time")

    if is_summative: header1.extend(["", "Total score / %d" % len(rlns)])
    rw.write(header1)
    rw.write(header2)

    for u in sorted_usernames:
        r = data[u]
        stud_score = 0
        content = [u, r['name']]
        for ex_id in ex_ids:
            if ex_id in r: ex_res = r[ex_id]
            else:
                ex_res = {
                    'completed': '',
                    'attempts': '',
                    'score': '',
                    'mean_attempt_time': ''
                }

            content.extend(["", "", ex_res['completed'], ex_res['attempts']])
            if is_summative:
                content.append(ex_res['score'])
                stud_score += (ex_res['score'] if isinstance(
                    ex_res['score'], float) else 0)
            content.append(ex_res['mean_attempt_time'])
        if is_summative: content.extend(["", stud_score])
        rw.write(content)

    rw.close()
Exemple #10
0
def gen_course_dashboard_report(ready_course, save_to_s3=False):
    dt = datetime.now()
    course_prefix = ready_course.handle.split('--')[0]
    course_suffix = ready_course.handle.split('--')[1]

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s-Dashboard.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
        course_prefix + '_' + course_suffix)
    s3_filepath = "%s/%s/reports/dashboard/%s" % (course_prefix, course_suffix,
                                                  report_name)

    rw = C2GReportWriter(save_to_s3, s3_filepath)

    # Title
    rw.write(content=[
        "Dashboard for %s (%s %d)" %
        (ready_course.title, ready_course.term.title(), ready_course.year)
    ],
             nl=1)

    # Members
    num_prof = ready_course.instructor_group.user_set.all().count()
    num_stud = ready_course.student_group.user_set.all().count()
    num_tas = ready_course.tas_group.user_set.all().count()
    num_rota = ready_course.readonly_tas_group.user_set.all().count()

    rw.write(content=["Members"])
    rw.write(content=[
        "Students", num_stud, "Professors", num_prof, "TAs", num_tas,
        "Readonly TAs", num_rota
    ],
             indent=1,
             nl=1)

    # Content
    live_exam_objects = Exam.objects.getByCourse(course=ready_course)
    all_exam_objects = Exam.objects.getByCourse(course=ready_course.image)
    exam_types = [li[0] for li in Exam.EXAM_TYPE_CHOICES]
    exam_content = {}
    for exam_type in exam_types:
        content_tuple = (all_exam_objects.filter(exam_type=exam_type),
                         live_exam_objects.filter(exam_type=exam_type))
        exam_content[exam_type] = content_tuple

    num_all_formative_problem_sets = exam_content["problemset"][0].filter(
        assessment_type="formative").count()
    num_live_formative_problem_sets = exam_content["problemset"][1].filter(
        assessment_type="formative").count()
    num_all_summative_problem_sets = exam_content["problemset"][0].filter(
        assessment_type="summative").count()
    num_live_summative_problem_sets = exam_content["problemset"][1].filter(
        assessment_type="summative").count()
    num_all_videos = Video.objects.getByCourse(
        course=ready_course.image).count()
    live_videos = Video.objects.getByCourse(course=ready_course)
    num_live_videos = live_videos.count()
    num_all_pages = AdditionalPage.objects.getByCourse(
        course=ready_course.image).count()
    live_additional_pages = AdditionalPage.objects.getByCourse(
        course=ready_course)
    num_live_pages = live_additional_pages.count()
    num_all_files = File.objects.getByCourse(course=ready_course.image).count()
    num_live_files = File.objects.getByCourse(course=ready_course).count()

    rw.write(content=["Content"])
    rw.write(content=[
        "Formative Quizzes", "Summative Quizzes", "Interactive Exercises",
        "Exams", "Surveys", "Videos", "Content Pages", "Files"
    ],
             indent=2)
    rw.write(content=[
        "All", num_all_formative_problem_sets, num_all_summative_problem_sets,
        exam_content["interactive_exercise"][0].count(),
        exam_content["exam"][0].count(), exam_content["survey"][0].count(),
        num_all_videos, num_all_pages, num_all_files
    ],
             indent=1)
    rw.write(content=[
        "Live", num_live_formative_problem_sets,
        num_live_summative_problem_sets,
        exam_content["interactive_exercise"][1].count(),
        exam_content["exam"][1].count(), exam_content["survey"][1].count(),
        num_live_videos, num_live_pages, num_live_files
    ],
             indent=1)

    # Activity
    rw.write(content=["Page Visits (Only live items are shown)"], nl=1)

    visits = {}
    for exam_type in exam_types:
        visits[
            Exam.Exam_HUMAN_TYPES_PLURAL[exam_type]] = get_visit_information(
                ready_course, exam_content[exam_type][1], exam_type)
    visits["Videos"] = get_visit_information(ready_course, live_videos,
                                             'video')
    visits["Content pages"] = get_visit_information(ready_course,
                                                    live_additional_pages,
                                                    'additional_page')
    visits["Forum"] = get_visit_information(ready_course, None, 'forum')

    content_types = [
        "Forum", "Quizzes", "Interactive Exercises", "Exams", "Surveys",
        "Videos", "Content pages"
    ]
    for content_type in content_types:
        rw.write(content=[content_type], indent=1)
        if content_type == "Forum":
            rw.write(content=[
                "", "", "", "Past day total", "Past day unique", "",
                "Past week total", "Past week unique", "", "all_time_total",
                "all_time_unique"
            ],
                     indent=1)
            rw.write(content=[
                "", "", "", visits["Forum"][0]['past_day_total'],
                visits["Forum"][0]['past_day_unique'], "",
                visits["Forum"][0]['past_week_total'],
                visits["Forum"][0]['past_week_unique'], "",
                visits["Forum"][0]['all_time_total'],
                visits["Forum"][0]['all_time_unique']
            ],
                     indent=1)
        else:
            if len(visits[content_type]) > 0:
                rw.write(content=[
                    "URL ID", "Title", "", "Past day total", "Past day unique",
                    "", "Past week total", "Past week unique", "",
                    "all_time_total", "all_time_unique"
                ],
                         indent=1)
                for item in visits[content_type]:
                    rw.write(content=[
                        item['item'].slug, item['item'].title, "",
                        item['past_day_total'], item['past_day_unique'], "",
                        item['past_week_total'], item['past_week_unique'], "",
                        item['all_time_total'], item['all_time_unique']
                    ],
                             indent=1)
            else:
                rw.write(content=["No live " + content_type.lower() + " yet."],
                         indent=2)
        rw.write([""])

    report_content = rw.writeout()
    return {
        'name':
        "%02d_%02d_%02d__%02d_%02d_%02d-%s-Dashboard.csv" %
        (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
         course_prefix + '_' + course_suffix),
        '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
    }
Exemple #12
0
def gen_assessment_full_report(ready_course, ready_exam, 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 = ready_exam.invideo
    assessment_type = ready_exam.assessment_type

    report_name = "%02d_%02d_%02d__%02d_%02d_%02d-%s.csv" % (
        dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second,
        ready_exam.slug)

    #I'm pretty sure we want to put all the assessment reports in one place and should be classified as problemset reports.
    #    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 exam data
    student_scores, student_field_scores = get_full_assessment_data(ready_exam)

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

    content = []
    content = [
        "", "Field", "Correct", "# Attempts", "Sub score", "Total score",
        "Max possible score"
    ]
    rw.write(content, indent=1)
    content = []

    for student_score in student_scores:
        name = student_score['student__first_name'] + " " + student_score[
            'student__last_name']
        content.extend([
            student_score['student__username'], name, "", "", "", "",
            student_score['score'], ready_exam.total_score
        ])
        rw.write(content)
        content = []

        for student_field_score in student_field_scores:
            if student_score['student__username'] == student_field_score[
                    'parent__record__student__username']:
                field_name = student_field_score['human_name']
                if not field_name:
                    field_name = student_field_score['field_name']
                content.extend([
                    field_name, student_field_score['correct'],
                    student_field_score['total_attempts'],
                    student_field_score['sub_score']
                ])
                rw.write(content, indent=2)
                content = []

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