コード例 #1
0
ファイル: dashboard.py プロジェクト: iqq/RunestoneServer
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,
    )
コード例 #2
0
def practice():
    if not session.timezoneoffset:
        session.timezoneoffset = 0

    feedback_saved = request.vars.get("feedback_saved", None)
    if feedback_saved is None:
        feedback_saved = ""

    (
        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,
        db,
    )

    try:
        db.useinfo.insert(
            sid=auth.user.username,
            act=message1 or "beginning practice",
            div_id="/runestone/assignments/practice",
            event="practice",
            timestamp=datetime.datetime.utcnow(),
            course_id=auth.user.course_name,
        )
    except Exception as e:
        logger.error(f"failed to insert log record for practice: {e}")

    if message1 != "":
        # session.flash = message1 + " " + message2
        return redirect(
            URL("practiceNotStartedYet",
                vars=dict(message1=message1, message2=message2)))

    # Since each authenticated user has only one active course, we retrieve the course this way.
    course = db(db.courses.id == auth.user.course_id).select().first()

    all_flashcards = db(
        (db.user_topic_practice.course_name == auth.user.course_name)
        & (db.user_topic_practice.user_id == auth.user.id)
        & (db.user_topic_practice.chapter_label == db.chapters.chapter_label)
        & (db.user_topic_practice.sub_chapter_label ==
           db.sub_chapters.sub_chapter_label)
        & (db.chapters.course_id == course.base_course)
        & (db.sub_chapters.chapter_id == db.chapters.id)).select(
            db.chapters.chapter_name,
            db.sub_chapters.sub_chapter_name,
            db.user_topic_practice.i_interval,
            db.user_topic_practice.next_eligible_date,
            db.user_topic_practice.e_factor,
            db.user_topic_practice.q,
            db.user_topic_practice.last_completed,
            orderby=db.user_topic_practice.id,
        )
    for f_card in all_flashcards:
        if interleaving == 1:
            f_card["remaining_days"] = max(
                0,
                (f_card.user_topic_practice.next_eligible_date -
                 now_local.date()).days,
            )
            # f_card["mastery_percent"] = int(100 * f_card["remaining_days"] // 55)
            f_card["mastery_percent"] = int(f_card["remaining_days"])
        else:
            # The maximum q is 5.0 and the minimum e_factor that indicates mastery of the topic is 2.5. `5 * 2.5 = 12.5`
            # I learned that when students under the blocking condition answer something wrong multiple times,
            # it becomes too difficult for them to pass it and the system asks them the same question many times
            # (because most subchapters have only one question). To solve this issue, I changed the blocking formula.
            f_card["mastery_percent"] = int(
                100 * f_card.user_topic_practice.e_factor *
                f_card.user_topic_practice.q / 12.5)
            if f_card["mastery_percent"] > 100:
                f_card["mastery_percent"] = 100

        f_card["mastery_color"] = "danger"
        if f_card["mastery_percent"] >= 75:
            f_card["mastery_color"] = "success"
        elif f_card["mastery_percent"] >= 50:
            f_card["mastery_color"] = "info"
        elif f_card["mastery_percent"] >= 25:
            f_card["mastery_color"] = "warning"

    # If an instructor removes the practice flag from a question in the middle of the semester
    # and students are in the middle of practicing it, the following code makes sure the practice tool does not crash.
    questions = []
    if len(presentable_flashcards) > 0:
        # Present the first one.
        flashcard = presentable_flashcards[0]
        # Get eligible questions.
        questions = _get_qualified_questions(course.base_course,
                                             flashcard.chapter_label,
                                             flashcard.sub_chapter_label, db)
    # If the student has any flashcards to practice and has not practiced enough to get their points for today or they
    # have intrinsic motivation to practice beyond what they are expected to do.
    if (available_flashcards_num > 0 and len(questions) > 0
            and (practiced_today_count != questions_to_complete_day
                 or request.vars.willing_to_continue or spacing == 0)):
        # Find index of the last question asked.
        question_names = [q.name for q in questions]

        try:
            qIndex = question_names.index(flashcard.question_name)
        except Exception:
            qIndex = 0

        # present the next one in the list after the last one that was asked
        question = questions[(qIndex + 1) % len(questions)]

        # This replacement is to render images
        question.htmlsrc = question.htmlsrc.replace(
            'src="../_static/', 'src="' + get_course_url("_static/"))
        question.htmlsrc = question.htmlsrc.replace("../_images/",
                                                    get_course_url("_images/"))

        autogradable = 1
        # If it is possible to autograde it:
        if (question.autograde
                is not None) or (question.question_type is not None
                                 and question.question_type in [
                                     "mchoice",
                                     "parsonsprob",
                                     "fillintheblank",
                                     "clickablearea",
                                     "dragndrop",
                                 ]):
            autogradable = 2

        questioninfo = [
            question.htmlsrc, question.name, question.id, autogradable
        ]

        # This is required to check the same question in do_check_answer().
        flashcard.question_name = question.name
        # This is required to only check answers after this timestamp in do_check_answer().
        flashcard.last_presented = now
        flashcard.timezoneoffset = (float(session.timezoneoffset)
                                    if "timezoneoffset" in session else 0)
        flashcard.update_record()

    else:
        questioninfo = None

        # Add a practice completion record for today, if there isn't one already.
        practice_completion_today = db(
            (db.user_topic_practice_completion.course_name ==
             auth.user.course_name)
            & (db.user_topic_practice_completion.user_id == auth.user.id)
            & (db.user_topic_practice_completion.practice_completion_date ==
               now_local.date()))
        if practice_completion_today.isempty():
            db.user_topic_practice_completion.insert(
                user_id=auth.user.id,
                course_name=auth.user.course_name,
                practice_completion_date=now_local.date(),
            )
            practice_completion_count = _get_practice_completion(
                auth.user.id, auth.user.course_name, spacing, db)
            if practice_graded == 1:
                # send practice grade via lti, if setup for that
                lti_record = _get_lti_record(session.oauth_consumer_key)
                practice_grade = _get_student_practice_grade(
                    auth.user.id, auth.user.course_name)
                course_settings = _get_course_practice_record(
                    auth.user.course_name)

                if spacing == 1:
                    total_possible_points = day_points * max_days
                    points_received = day_points * practice_completion_count
                else:
                    total_possible_points = question_points * max_questions
                    points_received = question_points * practice_completion_count

                if (lti_record and practice_grade
                        and practice_grade.lis_outcome_url
                        and practice_grade.lis_result_sourcedid
                        and course_settings):
                    if spacing == 1:
                        send_lti_grade(
                            assignment_points=max_days,
                            score=practice_completion_count,
                            consumer=lti_record.consumer,
                            secret=lti_record.secret,
                            outcome_url=practice_grade.lis_outcome_url,
                            result_sourcedid=practice_grade.
                            lis_result_sourcedid,
                        )
                    else:
                        send_lti_grade(
                            assignment_points=max_questions,
                            score=practice_completion_count,
                            consumer=lti_record.consumer,
                            secret=lti_record.secret,
                            outcome_url=practice_grade.lis_outcome_url,
                            result_sourcedid=practice_grade.
                            lis_result_sourcedid,
                        )

    set_latex_preamble(course.base_course)

    return dict(
        course=course,
        q=questioninfo,
        all_flashcards=all_flashcards,
        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,
        # 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,
        total_today_count=min(practice_today_left + practiced_today_count,
                              questions_to_complete_day),
        questions_to_complete_day=questions_to_complete_day,
        points_received=points_received,
        total_possible_points=total_possible_points,
        practice_graded=practice_graded,
        spacing=spacing,
        interleaving=interleaving,
        flashcard_creation_method=flashcard_creation_method,
        feedback_saved=feedback_saved,
    )
コード例 #3
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)