def get_json_response(self): # Currently accepts: { "buckets", "all", "newest" } to_show = self.request_string('show', 'buckets') past_days = self.request_int('past_days', 7) refresh_secs = self.request_int('rsecs', 30) today = dt.date.today() # We don't use App Engine Query filters so as to avoid adding entries to index.yaml days = [ today - dt.timedelta(days=i) for i in range(0, past_days) ] if to_show == 'all': exercise_names = [ex.name for ex in Exercise.get_all_use_cache()] return self.exercise_over_time_for_highcharts(exercise_names, days, 'All Exercises', showLegend=True) if to_show == 'newest': exercises = Exercise.get_all_use_cache() exercises.sort(key=lambda ex: ex.creation_date, reverse=True) exercise_names = [ex.name for ex in exercises] num_newest = self.request_int('newest', 5) exid = exercise_names[get_bucket_cursor(refresh_secs, num_newest)] title = 'Newest Exercises - %s' % Exercise.to_display_name(exid) return self.exercise_over_time_for_highcharts([exid], days, title, showLegend=True) num_buckets = self.request_int('buckets', NUM_BUCKETS) bucket_index = self.request_int('ix', 0) bucket_size = get_bucket_size(num_buckets, bucket_index) bucket_cursor = get_bucket_cursor(refresh_secs, bucket_size) exercise_names = exercises_in_bucket(num_buckets, bucket_index) exid = exercise_names[bucket_cursor] return self.exercise_over_time_for_highcharts([exid], days, Exercise.to_display_name(exid))
def exercise_progress_graph_context(user_data_student): if not user_data_student: return {} user = user_data_student.user exercise_data = {} exercises = Exercise.get_all_use_cache() user_exercises = UserExercise.get_for_user_use_cache(user) dict_user_exercises = {} for user_exercise in user_exercises: dict_user_exercises[user_exercise.exercise] = user_exercise for exercise in exercises: chart_link ="" status = "" color = "transparent" exercise_display = Exercise.to_display_name(exercise.name) ex_link = "/exercises?exid="+exercise.name hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, "Not Started", 0, 0) chart_link = "/profile/graph/exerciseproblems?student_email=%s&exercise_name=%s" % (user.email(), exercise.name) user_exercise = dict_user_exercises[exercise.name] if dict_user_exercises.has_key(exercise.name) else None if user_data_student.is_proficient_at(exercise.name): status = "Proficient" color = "proficient" if not user_data_student.is_explicitly_proficient_at(exercise.name): status = "Proficient (due to proficiency in a more advanced module)" elif user_exercise is not None and UserExercise.is_struggling_with(user_exercise, exercise): status = "Struggling" color = "struggling" elif user_exercise is not None and user_exercise.total_done > 0: status = "Started" color = "started" if len(status) > 0: hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % (exercise_display, status, user_exercise.streak if user_exercise is not None else 0, user_exercise.total_done if user_exercise is not None else 0) exercise_data[exercise.name] = { "short_name": exercise.short_name(), "chart_link": chart_link, "ex_link": ex_link, "hover": hover, "color": color } return { 'exercises': exercises, 'exercise_data': exercise_data, }
def exercise_progress_graph_context(user_data_student): if not user_data_student: return {} exercise_data = {} exercises = Exercise.get_all_use_cache() user_exercise_graph = UserExerciseGraph.get(user_data_student) review_exercise_names = user_exercise_graph.review_exercise_names() for exercise in exercises: chart_link ="" status = "" color = "transparent" exercise_display = Exercise.to_display_name(exercise.name) hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, "Not Started", '0%', 0) chart_link = "/profile/graph/exerciseproblems?student_email=%s&exercise_name=%s" % (user_data_student.email, exercise.name) graph_dict = user_exercise_graph.graph_dict(exercise.name) if graph_dict["proficient"]: if exercise.name in review_exercise_names: status = "Review" color = "review light" else: status = "Proficient" color = "proficient" if not graph_dict["explicitly_proficient"]: status = "Proficient (due to proficiency in a more advanced module)" elif graph_dict["struggling"]: status = "Struggling" color = "struggling" elif graph_dict["total_done"] > 0: status = "Started" color = "started" if len(status) > 0: hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % (exercise_display, status, UserExercise.to_progress_display(graph_dict["progress"]), graph_dict["total_done"]) exercise_data[exercise.name] = { "short_name": exercise.short_name(), "chart_link": chart_link, "ex_link": exercise.relative_url, "hover": hover, "color": color } return { 'exercises': exercises, 'exercise_data': exercise_data, }
def get_json_response(self): # Currently accepts: { "buckets", "all", "newest" } to_show = self.request_string('show', 'buckets') past_days = self.request_int('past_days', 7) refresh_secs = self.request_int('rsecs', 30) today = dt.date.today() # We don't use App Engine Query filters so as to avoid adding entries to index.yaml days = [today - dt.timedelta(days=i) for i in range(0, past_days)] if to_show == 'all': exercise_names = [ex.name for ex in Exercise.get_all_use_cache()] return self.exercise_over_time_for_highcharts(exercise_names, days, 'All Exercises', showLegend=True) if to_show == 'newest': exercises = Exercise.get_all_use_cache() exercises.sort(key=lambda ex: ex.creation_date, reverse=True) exercise_names = [ex.name for ex in exercises] num_newest = self.request_int('newest', 5) exid = exercise_names[get_bucket_cursor(refresh_secs, num_newest)] title = 'Newest Exercises - %s' % Exercise.to_display_name(exid) return self.exercise_over_time_for_highcharts([exid], days, title, showLegend=True) num_buckets = self.request_int('buckets', NUM_BUCKETS) bucket_index = self.request_int('ix', 0) bucket_size = get_bucket_size(num_buckets, bucket_index) bucket_cursor = get_bucket_cursor(refresh_secs, bucket_size) exercise_names = exercises_in_bucket(num_buckets, bucket_index) exid = exercise_names[bucket_cursor] return self.exercise_over_time_for_highcharts( [exid], days, Exercise.to_display_name(exid))
def description(self): dict_videos = {} dict_exercises = {} for activity in self.activities: dict_target = None name_activity = None if type(activity) == ProblemLog: name_activity = activity.exercise dict_target = dict_exercises elif type(activity) == VideoLog: name_activity = activity.video_title dict_target = dict_videos if dict_target is not None: # For older data that doesn't have video titles recorded if name_activity is None: name_activity = "Unknown" if not dict_target.has_key(name_activity): dict_target[name_activity] = True desc_videos = "" for key in dict_videos: if len(desc_videos) > 0: desc_videos += "<br/>" desc_videos += " - <em>%s</em>" % key if len(desc_videos) > 0: desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos desc_exercises = "" for key in dict_exercises: if len(desc_exercises) > 0: desc_exercises += "<br/>" desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key) if len(desc_exercises) > 0: desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises desc = ( "<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises return desc
def exercise_message(exercise, user_exercise_graph, sees_graph=False, review_mode=False): """Render UserExercise html for APIActionResults["exercise_message_html"] listener in khan-exercise.js. This is called **each time** a problem is either attempted or a hint is called (via /api/v1.py) returns nothing unless a user is struggling, proficient, etc. then it returns the appropriat template See Also: APIActionResults sees_graph is part of an ab_test to see if a small graph will help """ # TODO(david): Should we show a message if the user gets a problem wrong # after proficiency, to explain that this exercise needs to be reviewed? exercise_states = user_exercise_graph.states(exercise.name) if review_mode and user_exercise_graph.has_completed_review(): filename = 'exercise_message_review_finished.html' elif (exercise_states['proficient'] and not exercise_states['reviewing'] and not review_mode): if sees_graph: filename = 'exercise_message_proficient_withgraph.html' else: filename = 'exercise_message_proficient.html' elif exercise_states['struggling']: filename = 'exercise_message_struggling.html' suggested_prereqs = [] if exercise.prerequisites: proficient_exercises = user_exercise_graph.proficient_exercise_names() for prereq in exercise.prerequisites: if prereq not in proficient_exercises: suggested_prereqs.append({ 'ka_url': Exercise.get_relative_url(prereq), 'display_name': Exercise.to_display_name(prereq), }) exercise_states['suggested_prereqs'] = apijsonify.jsonify( suggested_prereqs) else: return None return shared_jinja.get().render_template(filename, **exercise_states)
def description(self): dict_videos = {} dict_exercises = {} for activity in self.activities: dict_target = None name_activity = None if type(activity) == ProblemLog: name_activity = activity.exercise dict_target = dict_exercises elif type(activity) == VideoLog: name_activity = activity.video_title dict_target = dict_videos if dict_target is not None: # For older data that doesn't have video titles recorded if name_activity is None: name_activity = "Unknown" if not dict_target.has_key(name_activity): dict_target[name_activity] = True desc_videos = "" for key in dict_videos: if len(desc_videos) > 0: desc_videos += "<br/>" desc_videos += " - <em>%s</em>" % key if len(desc_videos) > 0: desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos desc_exercises = "" for key in dict_exercises: if len(desc_exercises) > 0: desc_exercises += "<br/>" desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key) if len(desc_exercises) > 0: desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises desc = ("<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises return desc
def description(self): desc_videos = "" for key in self.dict_videos: if len(desc_videos) > 0: desc_videos += "<br/>" desc_videos += " - <em>%s</em>" % key if len(desc_videos) > 0: desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos desc_exercises = "" for key in self.dict_exercises: if len(desc_exercises) > 0: desc_exercises += "<br/>" desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key) if len(desc_exercises) > 0: desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises desc = ("<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises return desc
def description(self): desc_videos = "" for key in self.dict_videos: if len(desc_videos) > 0: desc_videos += "<br/>" desc_videos += " - <em>%s</em>" % key if len(desc_videos) > 0: desc_videos = "<br/><b>Videos:</b><br/>" + desc_videos desc_exercises = "" for key in self.dict_exercises: if len(desc_exercises) > 0: desc_exercises += "<br/>" desc_exercises += " - <em>%s</em>" % Exercise.to_display_name(key) if len(desc_exercises) > 0: desc_exercises = "<br/><b>Exercises:</b><br/>" + desc_exercises desc = ( "<b>%s</b> - <b>%s</b><br/>(<em>~%.0f min.</em>)" % (self.start.strftime("%I:%M%p"), self.end.strftime("%I:%M%p"), self.minutes_spent())) + "<br/>" + desc_videos + desc_exercises return desc
def exercise_progress_graph_context(user_data_student): if not user_data_student: return {} exercise_data = {} exercises = Exercise.get_all_use_cache() user_exercise_graph = UserExerciseGraph.get(user_data_student) review_exercise_names = user_exercise_graph.review_exercise_names() for exercise in exercises: chart_link = "" status = "" color = "transparent" exercise_display = Exercise.to_display_name(exercise.name) hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, "Not Started", '0%', 0) chart_link = "/profile/graph/exerciseproblems?student_email=%s&exercise_name=%s" % ( user_data_student.email, exercise.name) graph_dict = user_exercise_graph.graph_dict(exercise.name) if graph_dict["proficient"]: if exercise.name in review_exercise_names: status = "Review" color = "review light" else: status = "Proficient" color = "proficient" if not graph_dict["explicitly_proficient"]: status = "Proficient (due to proficiency in a more advanced module)" elif graph_dict["struggling"]: status = "Struggling" color = "struggling" elif graph_dict["total_done"] > 0: status = "Started" color = "started" if len(status) > 0: hover = "<b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Progress: %s</em><br/><em>Problems attempted: %s</em>" % ( exercise_display, status, UserExercise.to_progress_display( graph_dict["progress"]), graph_dict["total_done"]) exercise_data[exercise.name] = { "short_name": exercise.short_name(), "chart_link": chart_link, "ex_link": exercise.relative_url, "hover": hover, "color": color } return { 'exercises': exercises, 'exercise_data': exercise_data, }