Beispiel #1
0
def exercisemetrics():
    if "chapter" not in request.vars:
        logger.error(
            "It Appears exercisemetrics was called without any request vars")
        session.flash = "Cannot call exercisemetrics directly"
        redirect(URL("dashboard", "index"))
    chapter = request.vars["chapter"]
    base_course = (db(db.courses.course_name ==
                      auth.user.course_name).select().first().base_course)
    chapter = (db(((db.chapters.course_id == auth.user.course_name)
                   | (db.chapters.course_id == base_course))
                  & (db.chapters.chapter_label == chapter)).select().first())
    if not chapter:
        logger.error("Error -- No Chapter information for {} and {}".format(
            auth.user.course_name, request.vars["chapter"]))
        session.flash = "No Chapter information for {} and {}".format(
            auth.user.course_name, request.vars["chapter"])
        redirect(URL("dashboard", "index"))

    # TODO: When all old style courses were gone this can be just a base course
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id, chapter)
    data_analyzer.load_exercise_metrics(request.vars["id"])
    problem_metrics = data_analyzer.problem_metrics

    prob_id = request.vars["id"]
    answers = []
    attempt_histogram = []
    logger.debug(problem_metrics.problems)
    try:
        problem_metric = problem_metrics.problems[prob_id]
    except KeyError:
        session.flash = f"Not enough data for {prob_id}"
        redirect(request.env.http_referer)
    response_frequency = problem_metric.aggregate_responses

    for username, user_responses in six.iteritems(
            problem_metric.user_responses):
        responses = user_responses.responses[:4]
        responses += [""] * (4 - len(responses))
        answers.append({
            "user": user_responses.user,
            "username": user_responses.username,
            "answers": responses,
        })

    for attempts, count in six.iteritems(
            problem_metric.user_number_responses()):
        attempt_histogram.append({"attempts": attempts, "frequency": count})

    return dict(
        course=get_course_row(db.courses.ALL),
        answers=answers,
        response_frequency=response_frequency,
        attempt_histogram=attempt_histogram,
        exercise_label=problem_metric.problem_text,
    )
def studentreport():
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id)
    # todo: Test to see if vars.id is there -- if its not then load_user_metrics will crash
    # todo: This seems redundant with assignments/index  -- should use this one... id should be text sid
    data_analyzer.load_user_metrics(request.vars.id)
    data_analyzer.load_assignment_metrics(request.vars.id)

    chapters = []
    for chapter_label, chapter in six.iteritems(
            data_analyzer.chapter_progress.chapters):
        chapters.append({
            "label": chapter.chapter_label,
            "status": chapter.status_text(),
            "subchapters": chapter.get_sub_chapter_progress(),
        })
    activity = data_analyzer.formatted_activity.activities

    logger.debug("GRADES = %s", data_analyzer.grades)
    return dict(
        course=get_course_row(db.courses.ALL),
        user=data_analyzer.user,
        chapters=chapters,
        activity=activity,
        assignments=data_analyzer.grades,
    )
Beispiel #3
0
def exercisemetrics():
    if 'chapter' not in request.vars:
        logger.error(
            "It Appears exercisemetrics was called without any request vars")
        session.flash = "Cannot call exercisemetrics directly"
        redirect(URL('dashboard', 'index'))
    chapter = request.get_vars['chapter']
    chapter = db((db.chapters.course_id == auth.user.course_name)
                 & (db.chapters.chapter_label == chapter)).select().first()
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id, chapter)
    data_analyzer.load_exercise_metrics(request.get_vars["id"])
    problem_metrics = data_analyzer.problem_metrics

    prob_id = request.get_vars["id"]
    answers = []
    attempt_histogram = []
    logger.debug(problem_metrics.problems)
    problem_metric = problem_metrics.problems[prob_id]
    response_frequency = problem_metric.aggregate_responses

    for username, user_responses in six.iteritems(
            problem_metric.user_responses):
        responses = user_responses.responses[:4]
        responses += [''] * (4 - len(responses))
        answers.append({
            "user": user_responses.user,
            "username": user_responses.username,
            "answers": responses
        })

    for attempts, count in six.iteritems(
            problem_metric.user_number_responses()):
        attempt_histogram.append({"attempts": attempts, "frequency": count})

    return dict(course=get_course_row(db.courses.ALL),
                answers=answers,
                response_frequency=response_frequency,
                attempt_histogram=attempt_histogram,
                exercise_label=problem_metric.problem_text)
Beispiel #4
0
def index():
    if not auth.user:
        session.flash = "Please Login"
        return redirect(URL('default', 'index'))
    if 'sid' not in request.vars:
        #return redirect(URL('assignments','index') + '?sid=%s' % (auth.user.username))
        request.vars.sid = auth.user.username

    student = db(db.auth_user.username == request.vars.sid).select(
        db.auth_user.id,
        db.auth_user.username,
        db.auth_user.first_name,
        db.auth_user.last_name,
        db.auth_user.email,
    ).first()
    if not student:
        return redirect(URL('assignments', 'index'))

    if auth.user.course_name in ['thinkcspy', 'pythonds', 'JavaReview', 'webfundamentals', 'StudentCSP', 'apcsareview']:
        session.flash = "{} is not a graded course".format(auth.user.course_name)
        return redirect(URL('default', 'user'))

    data_analyzer = DashboardDataAnalyzer(auth.user.course_id)
    data_analyzer.load_user_metrics(request.vars.sid)
    data_analyzer.load_assignment_metrics(request.vars.sid, studentView=True)

    chapters = []
    for chapter_label, chapter in six.iteritems(data_analyzer.chapter_progress.chapters):
        chapters.append({
            "label": chapter.chapter_label,
            "status": chapter.status_text(),
            "subchapters": chapter.get_sub_chapter_progress()
        })
    activity = data_analyzer.formatted_activity.activities

    (now,
     now_local,
     message1,
     message2,
     practice_graded,
     spacing,
     interleaving,
     practice_completion_count,
     remaining_days,
     max_days,
     max_questions,
     day_points,
     question_points,
     presentable_flashcards,
     available_flashcards_num,
     practiced_today_count,
     questions_to_complete_day,
     practice_today_left,
     points_received,
     total_possible_points,
     flashcard_creation_method) = _get_practice_data(auth.user,
                                                     float(session.timezoneoffset) if 'timezoneoffset' in session else 0)

    return dict(student=student, course_id=auth.user.course_id, course_name=auth.user.course_name,
                user=data_analyzer.user, chapters=chapters, activity=activity, assignments=data_analyzer.grades,
                practice_message1=message1, practice_message2=message2,
                practice_graded=practice_graded, flashcard_count=available_flashcards_num,
                # The number of days the student has completed their practice.
                practice_completion_count=practice_completion_count,
                remaining_days=remaining_days, max_questions=max_questions, max_days=max_days,
                total_today_count=min(practice_today_left + practiced_today_count, questions_to_complete_day),
                # The number of times remaining to practice today to get the completion point.
                practice_today_left=practice_today_left,
                # The number of times this user has submitted their practice from the beginning of today (12:00 am)
                # till now.
                practiced_today_count=practiced_today_count,
                points_received=points_received,
                total_possible_points=total_possible_points,
                spacing=spacing,
                interleaving=interleaving
                )
Beispiel #5
0
def index():
    selected_chapter = None
    questions = []
    sections = []

    if settings.academy_mode and not settings.docker_institution_mode:
        if auth.user.course_name in [
                "thinkcspy",
                "pythonds",
                "JavaReview",
                "JavaReview-RU",
                "StudentCSP",
                "csawesome",
                "fopp",
        ]:
            session.flash = "Student Progress page not available for {}".format(
                auth.user.course_name)
            return redirect(URL("admin", "admin"))

    course = db(db.courses.id == auth.user.course_id).select().first()
    assignments = db(db.assignments.course == course.id).select(
        db.assignments.ALL, orderby=db.assignments.name)
    chapters = db(db.chapters.course_id == course.base_course).select(
        orderby=db.chapters.chapter_num)

    logger.debug("getting chapters for {}".format(auth.user.course_name))
    chapget = ChapterGet(chapters)
    for chapter in chapters.find(
            lambda chapter: chapter.chapter_label == request.vars["chapter"]):
        selected_chapter = chapter
    if selected_chapter is None:
        selected_chapter = chapters.first()

    logger.debug("making an analyzer")
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id,
                                          selected_chapter)
    logger.debug("loading chapter metrics for course {}".format(
        auth.user.course_name))
    data_analyzer.load_chapter_metrics(selected_chapter)
    logger.debug("loading problem metrics")
    problem_metrics = data_analyzer.problem_metrics
    logger.debug("loading progress_metrics metrics")
    progress_metrics = data_analyzer.progress_metrics

    logger.debug("starting problem_id, metric loop")
    for problem_id, metric in six.iteritems(problem_metrics.problems):
        stats = metric.user_response_stats()

        if data_analyzer.questions[problem_id]:
            chtmp = data_analyzer.questions[problem_id].chapter
            schtmp = data_analyzer.questions[problem_id].subchapter
            entry = {
                "id": problem_id,
                "text": metric.problem_text,
                "chapter": chtmp,
                "chapter_title": chapget.ChapterName(chtmp),
                "chapter_number": chapget.ChapterNumber(chtmp),
                "sub_chapter": schtmp,
                "sub_chapter_number": chapget.SectionNumber(chtmp, schtmp),
                "sub_chapter_title": chapget.SectionName(chtmp, schtmp),
                "correct": stats[2],
                "correct_mult_attempt": stats[3],
                "incomplete": stats[1],
                "not_attempted": stats[0],
                "attemptedBy": stats[1] + stats[2] + stats[3],
            }
        else:
            entry = {
                "id": problem_id,
                "text": metric.problem_text,
                "chapter": "unknown",
                "sub_chapter": "unknown",
                "sub_chapter_number": 0,
                "sub_chapter_title": "unknown",
                "chapter_title": "unknown",
                "correct": stats[2],
                "correct_mult_attempt": stats[3],
                "incomplete": stats[1],
                "not_attempted": stats[0],
                "attemptedBy": stats[1] + stats[2] + stats[3],
            }
        questions.append(entry)
        logger.debug("ADDING QUESTION %s ", entry["chapter"])

    logger.debug("getting questions")
    try:
        questions = sorted(questions,
                           key=itemgetter("chapter", "sub_chapter_number"))
    except Exception as e:
        logger.error("FAILED TO SORT {} Error detail: {}".format(questions, e))
    logger.debug("starting sub_chapter loop")
    for sub_chapter, metric in six.iteritems(progress_metrics.sub_chapters):
        sections.append({
            "id":
            metric.sub_chapter_label,
            "text":
            metric.sub_chapter_text,
            "name":
            metric.sub_chapter_name,
            "number":
            chapget.SectionNumber(selected_chapter.chapter_label,
                                  metric.sub_chapter_label),
            # FIX: Using selected_chapter here might be a kludge
            # Better if metric contained chapter numbers associated with sub_chapters
            "readPercent":
            metric.get_completed_percent(),
            "startedPercent":
            metric.get_started_percent(),
            "unreadPercent":
            metric.get_not_started_percent(),
        })

    read_data = []
    correct_data = []
    missed_data = []
    recent_data = []
    recent_correct = []
    recent_missed = []
    daily_data = []
    daily_correct = []
    daily_missed = []
    logger.debug("getting user activity")
    user_activity = data_analyzer.user_activity

    # All of this can be replaced by a nice crosstab call
    # See UserActivityCrosstab.ipynb
    for user, activity in six.iteritems(user_activity.user_activities):
        read_data.append({
            "student": activity.
            name,  # causes username instead of full name to show in the report, but it works  ?? how to display the name but use the username on click??
            "sid": activity.username,
            "count": activity.get_page_views(),
        })
        correct_data.append({
            "student": activity.
            name,  # causes username instead of full name to show in the report, but it works  ?? how to display the name but use the username on click??
            "sid": activity.username,
            "count": activity.get_correct_count(),
        })
        missed_data.append({
            "student": activity.
            name,  # causes username instead of full name to show in the report, but it works  ?? how to display the name but use the username on click??
            "sid": activity.username,
            "count": activity.get_missed_count(),
        })

        recent_data.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_recent_page_views(),
        })

        recent_correct.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_recent_correct(),
        })
        recent_missed.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_recent_missed(),
        })

        daily_data.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_daily_page_views(),
        })

        daily_correct.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_daily_correct(),
        })
        daily_missed.append({
            "student": activity.name,
            "sid": activity.username,
            "count": activity.get_daily_missed(),
        })

    logger.debug("finishing")
    # TODO -- this is not right and explains why all are the same!!
    studentactivity = [
        {
            "data": read_data,
            "name": "Sections Read"
        },
        {
            "data": correct_data,
            "name": "Exercises Correct"
        },
        {
            "data": missed_data,
            "name": "Exercises Missed"
        },
    ]

    recentactivity = [
        {
            "data": recent_data,
            "name": "Sections Read"
        },
        {
            "data": recent_correct,
            "name": "Exercises Correct"
        },
        {
            "data": recent_missed,
            "name": "Exercises Missed"
        },
    ]

    dailyactivity = [
        {
            "data": daily_data,
            "name": "Sections Read"
        },
        {
            "data": daily_correct,
            "name": "Exercises Correct"
        },
        {
            "data": daily_missed,
            "name": "Exercises Missed"
        },
    ]

    return dict(
        assignments=assignments,
        course=course,
        questions=questions,
        sections=sections,
        chapters=chapters,
        selected_chapter=selected_chapter,
        studentactivity=studentactivity,
        recentactivity=recentactivity,
        dailyactivity=dailyactivity,
    )
Beispiel #6
0
def studentreport():
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id)
    for_dashboard = verifyInstructorStatus(auth.user.course_id, auth.user.id)
    if "id" in request.vars and for_dashboard:
        sid = request.vars.id
    else:
        sid = auth.user.username
        response.view = "assignments/index.html"

    data_analyzer.load_user_metrics(sid)
    data_analyzer.load_assignment_metrics(sid, not for_dashboard)

    chapters = []
    for chapter_label, chapter in six.iteritems(
            data_analyzer.chapter_progress.chapters):
        chapters.append({
            "label": chapter.chapter_label,
            "status": chapter.status_text(),
            "subchapters": chapter.get_sub_chapter_progress(),
        })
    activity = data_analyzer.formatted_activity

    logger.debug("GRADES = %s", data_analyzer.grades)

    pd_dict = dict()
    if response.view == "assignments/index.html":
        (
            pd_dict["now"],
            pd_dict["now_local"],
            pd_dict["practice_message1"],
            pd_dict["practice_message2"],
            pd_dict["practice_graded"],
            pd_dict["spacing"],
            pd_dict["interleaving"],
            pd_dict["practice_completion_count"],
            pd_dict["remaining_days"],
            pd_dict["max_days"],
            pd_dict["max_questions"],
            pd_dict["day_points"],
            pd_dict["question_points"],
            pd_dict["presentable_flashcards"],
            pd_dict["flashcard_count"],
            pd_dict["practiced_today_count"],
            pd_dict["questions_to_complete_day"],
            pd_dict["practice_today_left"],
            pd_dict["points_received"],
            pd_dict["total_possible_points"],
            pd_dict["flashcard_creation_method"],
        ) = _get_practice_data(
            auth.user,
            float(session.timezoneoffset)
            if "timezoneoffset" in session else 0,
            db,
        )
        pd_dict["total_today_count"] = min(
            pd_dict["practice_today_left"] + pd_dict["practiced_today_count"],
            pd_dict["questions_to_complete_day"],
        )

    if request.vars.action == "dlcsv":
        mtbl = pd.read_sql_query(
            """
        select * from useinfo where sid = %(sid)s and course_id = %(course)s
        """,
            settings.database_uri,
            params={
                "sid": sid,
                "course": auth.user.course_name
            },
        )
        response.headers["Content-Type"] = "application/vnd.ms-excel"
        response.headers[
            "Content-Disposition"] = "attachment; filename=data_for_{}.csv".format(
                sid)
        session.flash = f"Downloading to data_for_{sid}.csv"
        return mtbl.to_csv(na_rep=" ")

    if request.vars.action == "dlcode":
        mtbl = pd.read_sql_query(
            """
        select * from code where sid = %(sid)s and course_id = %(course)s
        """,
            settings.database_uri,
            params={
                "sid": auth.user.username,
                "course": auth.user.course_id
            },
        )
        response.headers["Content-Type"] = "application/vnd.ms-excel"
        response.headers[
            "Content-Disposition"] = "attachment; filename=code_for_{}.csv".format(
                sid)
        session.flash = f"Downloading to code_for_{sid}.csv"
        return mtbl.to_csv(na_rep=" ")

    return dict(
        course=get_course_row(db.courses.ALL),
        user=data_analyzer.user,
        chapters=chapters,
        activity=activity,
        assignments=data_analyzer.grades,
        **pd_dict,
    )
Beispiel #7
0
def studentreport():
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id)
    for_dashboard = verifyInstructorStatus(auth.user.course_id, auth.user.id)
    if "id" in request.vars and for_dashboard:
        sid = request.vars.id
    else:
        sid = auth.user.username
        response.view = "assignments/index.html"

    data_analyzer.load_user_metrics(sid)
    data_analyzer.load_assignment_metrics(sid)

    chapters = []
    for chapter_label, chapter in six.iteritems(
            data_analyzer.chapter_progress.chapters):
        chapters.append({
            "label": chapter.chapter_label,
            "status": chapter.status_text(),
            "subchapters": chapter.get_sub_chapter_progress(),
        })
    activity = data_analyzer.formatted_activity

    logger.debug("GRADES = %s", data_analyzer.grades)

    pd = dict()
    if response.view == "assignments/index.html":
        (
            pd["now"],
            pd["now_local"],
            pd["practice_message1"],
            pd["practice_message2"],
            pd["practice_graded"],
            pd["spacing"],
            pd["interleaving"],
            pd["practice_completion_count"],
            pd["remaining_days"],
            pd["max_days"],
            pd["max_questions"],
            pd["day_points"],
            pd["question_points"],
            pd["presentable_flashcards"],
            pd["flashcard_count"],
            pd["practiced_today_count"],
            pd["questions_to_complete_day"],
            pd["practice_today_left"],
            pd["points_received"],
            pd["total_possible_points"],
            pd["flashcard_creation_method"],
        ) = _get_practice_data(
            auth.user,
            float(session.timezoneoffset)
            if "timezoneoffset" in session else 0,
            db,
        )
        pd["total_today_count"] = min(
            pd["practice_today_left"] + pd["practiced_today_count"],
            pd["questions_to_complete_day"],
        )

    return dict(course=get_course_row(db.courses.ALL),
                user=data_analyzer.user,
                chapters=chapters,
                activity=activity,
                assignments=data_analyzer.grades,
                **pd)
Beispiel #8
0
def index():
    selected_chapter = None
    questions = []
    sections = []

    if settings.academy_mode and not settings.docker_institution_mode:
        if auth.user.course_name in ['thinkcspy','pythonds','JavaReview','JavaReview-RU', 'StudentCSP']:
            session.flash = "Student Progress page not available for {}".format(auth.user.course_name)
            return redirect(URL('admin','admin'))

    course = db(db.courses.id == auth.user.course_id).select().first()
    assignments = db(db.assignments.course == course.id).select(db.assignments.ALL, orderby=db.assignments.name)
    logger.debug("getting chapters for {}".format(auth.user.course_name))
    chapters = db(db.chapters.course_id == course.base_course).select()
    chap_map = {}
    for chapter in chapters:
        chap_map[chapter.chapter_label] = chapter.chapter_name
    for chapter in chapters.find(lambda chapter: chapter.chapter_label==request.vars['chapter']):
        selected_chapter = chapter
    if selected_chapter is None:
        selected_chapter = chapters.first()

    logger.debug("making an analyzer")
    data_analyzer = DashboardDataAnalyzer(auth.user.course_id,selected_chapter)
    logger.debug("loading chapter metrics for course {}".format(auth.user.course_name))
    data_analyzer.load_chapter_metrics(selected_chapter)
    logger.debug("loading problem metrics")
    problem_metrics = data_analyzer.problem_metrics
    logger.debug("loading progress_metrics metrics")
    progress_metrics = data_analyzer.progress_metrics

    logger.debug("starting problem_id, metric loop")
    for problem_id, metric in six.iteritems(problem_metrics.problems):
        stats = metric.user_response_stats()

        if data_analyzer.questions[problem_id]:
            chtmp = data_analyzer.questions[problem_id].chapter
            entry = {
                "id": problem_id,
                "text": metric.problem_text,
                "chapter": chtmp,
                "chapter_title": chap_map.get(chtmp,chtmp),
                "sub_chapter": data_analyzer.questions[problem_id].subchapter,
                "correct": stats[2],
                "correct_mult_attempt": stats[3],
                "incomplete": stats[1],
                "not_attempted": stats[0],
                "attemptedBy": stats[1] + stats[2] + stats[3]
                }
        else:
            entry = {
                "id": problem_id,
                "text": metric.problem_text,
                "chapter": "unknown",
                "sub_chapter": "unknown",
                "chapter_title": "unknown",
                "correct": stats[2],
                "correct_mult_attempt": stats[3],
                "incomplete": stats[1],
                "not_attempted": stats[0],
                "attemptedBy": stats[1] + stats[2] + stats[3]
                }
        questions.append(entry)
        logger.debug("ADDING QUESTION %s ", entry["chapter"])

    logger.debug("getting questsions")
    questions = sorted(questions, key=itemgetter("chapter"))
    logger.debug("starting sub_chapter loop")
    for sub_chapter, metric in six.iteritems(progress_metrics.sub_chapters):
        sections.append({
            "id": metric.sub_chapter_label,
            "text": metric.sub_chapter_text,
            "name": metric.sub_chapter_name,
            "readPercent": metric.get_completed_percent(),
            "startedPercent": metric.get_started_percent(),
            "unreadPercent": metric.get_not_started_percent()
            })

    read_data = []
    recent_data = []
    logger.debug("getting user activity")
    user_activity = data_analyzer.user_activity

    for user, activity in six.iteritems(user_activity.user_activities):
        read_data.append({
            "student":activity.name,  # causes username instead of full name to show in the report, but it works  ?? how to display the name but use the username on click??
            "sid":activity.username,
            "count":activity.get_page_views()
            })

        recent_data.append({
            "student":activity.name,
            "sid":activity.username,
            "count":activity.get_recent_page_views()
            })

    logger.debug("finishing")
    studentactivity = [{
    "data":read_data,
    "name":"Sections Read"
    },{
    "data":read_data,
    "name":"Exercises Correct"
    },{
    "data":read_data,
    "name":"Exercises Missed"
    }]

    recentactivity = [{
    "data":recent_data,
    "name":"Sections Read"
    },{
    "data":recent_data,
    "name":"Exercises Correct"
    },{
    "data":recent_data,
    "name":"Exercises Missed"
    }]

    return dict(assignments=assignments, course=course, questions=questions, sections=sections, chapters=chapters, selected_chapter=selected_chapter, studentactivity=studentactivity, recentactivity=recentactivity)