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