Beispiel #1
0
    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))
Beispiel #2
0
    def get_use_cache(self):
        params = self.get_request_params()

        # Get the maximum so we know how the data label circles should be scaled
        most_new_users = 1
        ex_stat_dict = {}
        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name,
                                                 params['interested_day'])
            ex_stat_dict[ex.name] = stat
            if stat:
                most_new_users = max(most_new_users, stat.num_new_users())

        data_points = []
        min_y, max_y = -1, 1
        for ex in Exercise.get_all_use_cache():
            stat = ex_stat_dict[ex.name]

            y, x = -int(ex.h_position), int(ex.v_position)

            min_y, max_y = min(y, min_y), max(y, max_y)

            # Set the area of the circle proportional to the data value
            radius = 1
            if stat:
                radius = math.sqrt(
                    float(stat.num_new_users()) /
                    most_new_users) * MAX_POINT_RADIUS

            point = {
                'x': x,
                'y': y,
                'name': ex.display_name,
                'marker': {
                    'radius': max(radius, 1)
                },
            }
            data_points.append(point)

        context = {
            'title': 'Exercises map - First attempts',
            'series': {
                'name': 'First attempts',
                'data_values': json.dumps(data_points),
            },
            'minYValue': min_y - 1,
            'maxYValue': max_y + 1,
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_scatter_map.json', context)
Beispiel #3
0
    def get_use_cache(self):
        params = self.get_request_params()

        # Get the maximum so we know how the data label circles should be scaled
        most_new_users = 1
        ex_stat_dict = {}
        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, params['interested_day'])
            ex_stat_dict[ex.name] = stat
            if stat:
                most_new_users = max(most_new_users, stat.num_new_users())

        data_points = []
        min_y, max_y = -1, 1
        for ex in Exercise.get_all_use_cache():
            stat = ex_stat_dict[ex.name]

            y, x = -int(ex.h_position), int(ex.v_position)

            min_y, max_y = min(y, min_y), max(y, max_y)

            # Set the area of the circle proportional to the data value
            radius = 1
            if stat:
                radius = math.sqrt(float(stat.num_new_users()) / most_new_users) * MAX_POINT_RADIUS

            point = {
                'x': x,
                'y': y,
                'name': ex.display_name,
                'marker': {
                    'radius': max(radius, 1)
                },
            }
            data_points.append(point)

        context = {
            'title': 'Exercises map - First attempts',
            'series': {
                'name': 'First attempts',
                'data_values': json.dumps(data_points),
            },
            'minYValue': min_y - 1,
            'maxYValue': max_y + 1,
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_scatter_map.json', context)
Beispiel #4
0
    def exercise_counter_for_geckoboard_rag():
        exercises = Exercise.get_all_use_cache()
        exercises.sort(key=lambda ex: ex.creation_date, reverse=True)

        last_exercise = exercises[0]
        num_exercises = len(exercises)
        last_exercise_author = last_exercise.author.nickname(
        ) if last_exercise.author else 'random person'

        text = "Thanks %s for %s!" % (last_exercise_author,
                                      last_exercise.display_name)

        return {
            'item': [
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': num_exercises,
                    'text': text,
                },
            ]
        }
Beispiel #5
0
    def exercise_counter_for_geckoboard_rag():
        exercises = Exercise.get_all_use_cache()
        exercises.sort(key=lambda ex: ex.creation_date, reverse=True)

        last_exercise = exercises[0]
        num_exercises = len(exercises)
        last_exercise_author = last_exercise.author.nickname() if last_exercise.author else 'random person'

        text = "Thanks %s for %s!" % (last_exercise_author, last_exercise.display_name)

        return {
            'item': [
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': None,
                    'text': '',
                },
                {
                    'value': num_exercises,
                    'text': text,
                },
            ]
        }
Beispiel #6
0
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]
Beispiel #7
0
def exercise_title_dicts():
    return [{
        "title": exercise.display_name,
        "key": str(exercise.key()),
        "relative_url": exercise.relative_url,
        "id": exercise.name,
    } for exercise in Exercise.get_all_use_cache() if not exercise.summative]
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, }
Beispiel #10
0
    def get(self):
        date_to_set = self.request_date('date', "%Y/%m/%d")

        exercises = Exercise.get_all_use_cache()
        updated = []
        for ex in exercises:
            ex.creation_date = date_to_set
            updated.append(ex)

        db.put(updated)
Beispiel #11
0
    def get_ip_addresses_for_geckoboard_map(date):
        ip_addresses = []

        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, date)

            if stat:
                ip_addresses += stat.histogram.get('ip_addresses', [])

        return {'points': {'point': [{'ip': addr} for addr in ip_addresses]}}
Beispiel #12
0
    def get(self):
        date_to_set = self.request_date('date', "%Y/%m/%d")

        exercises = Exercise.get_all_use_cache()
        updated = []
        for ex in exercises:
            ex.creation_date = date_to_set
            updated.append(ex)

        db.put(updated)
Beispiel #13
0
    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))
Beispiel #14
0
def exercises_in_bucket(num_buckets, bucket_index):
    exercise_names = [ex.name for ex in Exercise.get_all_use_cache()]
    exercise_names.sort()

    # These calculations evenly distribute exercises among buckets, with excess
    # going to the first few buckets.
    # In particular, max_capacity(buckets) - min_capacity(buckets) <= 1.
    num_exercises = len(exercise_names)
    min_bucket_size = num_exercises / num_buckets
    bucket_rem = num_exercises % num_buckets

    first = bucket_index * min_bucket_size + min(bucket_rem, bucket_index)
    return exercise_names[ first : first + get_bucket_size(num_buckets, bucket_index) ]
Beispiel #15
0
    def get_ip_addresses_for_geckoboard_map(date):
        ip_addresses = []

        for ex in Exercise.get_all_use_cache():
            stat = ExerciseStatistic.get_by_date(ex.name, date)

            if stat:
                ip_addresses += stat.histogram.get('ip_addresses', [])

        return {
            'points': {
                'point': [{'ip': addr} for addr in ip_addresses]
            }
        }
Beispiel #16
0
def exercises_in_bucket(num_buckets, bucket_index):
    exercise_names = [ex.name for ex in Exercise.get_all_use_cache()]
    exercise_names.sort()

    # These calculations evenly distribute exercises among buckets, with excess
    # going to the first few buckets.
    # In particular, max_capacity(buckets) - min_capacity(buckets) <= 1.
    num_exercises = len(exercise_names)
    min_bucket_size = num_exercises / num_buckets
    bucket_rem = num_exercises % num_buckets

    first = bucket_index * min_bucket_size + min(bucket_rem, bucket_index)
    return exercise_names[first:first +
                          get_bucket_size(num_buckets, bucket_index)]
Beispiel #17
0
    def get_histogram_spline_for_highcharts(self, earliest_dt=dt.datetime.min):
        histogram = {}
        for ex in Exercise.get_all_use_cache():
            if ex.creation_date:
                creation_day = dt.datetime.combine(ex.creation_date, dt.time())
                timestamp = to_unix_secs(creation_day) * 1000
                histogram[timestamp] = histogram.get(timestamp, 0) + 1

        total_exercises = {}
        prev_value = 0
        for day, value in sorted(histogram.items()):
            prev_value = total_exercises[day] = prev_value + value

        # Only retain recent dates
        earliest_unix = to_unix_secs(earliest_dt) * 1000
        histogram = [[k, v] for k, v in histogram.items()
                     if k >= earliest_unix]
        total_exercises = [[k, v] for k, v in total_exercises.items()
                           if k >= earliest_unix]

        context = {
            'series': [{
                'name': 'Histogram (created per day)',
                'type': 'column',
                'data_values': json.dumps(histogram),
                'axis': 0,
            }, {
                'name': 'Total exercises',
                'type': 'spline',
                'data_values': json.dumps(total_exercises),
                'axis': 1,
            }],
            # Let highcharts determine the scales for now.
            'axes': [
                {
                    'max': 'null'
                },
                {
                    'max': 'null'
                },
            ],
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_exercises_created_histogram.json',
            context)
Beispiel #18
0
def add_related_exercises(videos):
    logging.info("%s videos", len(videos))

    exercises = {e.key():e for e in Exercise.get_all_use_cache()}
    relations = {}
    logging.info("%s exercises", len(exercises))
    for exvid in ExerciseVideo.all().run():
        ex = exercises.get(exvid.key_for_exercise())
        if ex:
            relations.setdefault(exvid.key_for_video(),[]).append(ex)

    for exs in relations.itervalues():
        exs.sort(key=lambda e: (e.v_position, e.h_position))

    logging.info("%s related videos", len(relations))
    for vid in videos:
        exs = relations.get(vid.key()) or []
        vid.cached_related_exercises = exs
Beispiel #19
0
def add_related_exercises(videos):
    logging.info("%s videos", len(videos))

    exercises = {e.key(): e for e in Exercise.get_all_use_cache()}
    relations = {}
    logging.info("%s exercises", len(exercises))
    for exvid in ExerciseVideo.all().run():
        ex = exercises.get(exvid.key_for_exercise())
        if ex:
            relations.setdefault(exvid.key_for_video(), []).append(ex)

    for exs in relations.itervalues():
        exs.sort(key=lambda e: (e.v_position, e.h_position))

    logging.info("%s related videos", len(relations))
    for vid in videos:
        exs = relations.get(vid.key()) or []
        vid.cached_related_exercises = exs
Beispiel #20
0
    def get_histogram_spline_for_highcharts(self, earliest_dt=dt.datetime.min):
        histogram = {}
        for ex in Exercise.get_all_use_cache():
            if ex.creation_date:
                creation_day = dt.datetime.combine(ex.creation_date, dt.time())
                timestamp = to_unix_secs(creation_day) * 1000
                histogram[timestamp] = histogram.get(timestamp, 0) + 1

        total_exercises = {}
        prev_value = 0
        for day, value in sorted(histogram.items()):
            prev_value = total_exercises[day] = prev_value + value

        # Only retain recent dates
        earliest_unix = to_unix_secs(earliest_dt) * 1000
        histogram = [[k,v] for k,v in histogram.items() if k >= earliest_unix]
        total_exercises = [[k,v] for k,v in total_exercises.items() if k >= earliest_unix]

        context = {
            'series': [
                {
                    'name': 'Histogram (created per day)',
                    'type': 'column',
                    'data_values': json.dumps(histogram),
                    'axis': 0,
                },
                {
                    'name': 'Total exercises',
                    'type': 'spline',
                    'data_values': json.dumps(total_exercises),
                    'axis': 1,
                }
            ],
            # Let highcharts determine the scales for now.
            'axes': [
                { 'max': 'null' },
                { 'max': 'null' },
            ],
        }

        return self.render_jinja2_template_to_string(
            'exercisestats/highcharts_exercises_created_histogram.json', context)
def get_content_data():
    topics = {str(t.key()):(idx, t) for idx, t in enumerate(Topic.get_visible_topics())}
    topic_names = {}
    def get_topics_of(item):
        def g():
            if not item.topic_string_keys:
                return
            seen = set()
            for tk in item.topic_string_keys:
                try:
                    idx, topic = topics[tk]
                except KeyError:
                    continue
                for depth, tk2 in enumerate(topic.ancestor_keys[:-1][::-1]):
                    try:
                        idx2, topic2 = topics[str(tk2)]
                    except KeyError:
                        continue
                    if idx2 in seen:
                        continue
                    seen.add(idx2)
                    topic_names[idx2] = topic2.title
                    # use depth for sorting by topic level
                    yield depth, idx2
        return [idx for _, idx in sorted(g())]

    videos = {video.key().id():
        dict(
            key_id=video.key().id(),
            name=video.readable_id,
            display_name=video.title,
            topics=get_topics_of(video)
        ) for video in Video.get_all()}

    exercises = {exercise.name:
        dict(
            name=exercise.name,
            display_name=exercise.display_name,
            topics=get_topics_of(exercise),
        ) for exercise in Exercise.get_all_use_cache()}

    return topic_names, videos, exercises
def class_progress_report_graph_context(user_data, list_students):
    if not user_data:
        return {}

    list_students = sorted(list_students, key=lambda student: student.nickname)

    student_email_pairs = [
        (escape(s.email),
         (s.nickname[:14] + '...') if len(s.nickname) > 17 else s.nickname)
        for s in list_students
    ]
    emails_escapejsed = [escapejs(s.email) for s in list_students]

    exercises_all = Exercise.get_all_use_cache()
    user_exercise_graphs = UserExerciseGraph.get(list_students)

    exercises_found = []

    for exercise in exercises_all:
        for user_exercise_graph in user_exercise_graphs:
            graph_dict = user_exercise_graph.graph_dict(exercise.name)
            if graph_dict and graph_dict["total_done"]:
                exercises_found.append(exercise)
                break

    exercise_names = [(e.name, e.display_name, escapejs(e.name))
                      for e in exercises_found]
    exercise_list = [{
        'name': e.name,
        'display_name': e.display_name
    } for e in exercises_found]

    videos_all = Video.get_all()
    all_video_progress = dict(
        zip(list_students, get_video_progress_for_students(list_students)))
    videos_found = reduce(set.union, all_video_progress.itervalues(), set())

    videos_found = [
        video for video in videos_all if video.key().id() in videos_found
    ]
    video_list = [{
        'name': v.readable_id,
        'display_name': v.title
    } for v in videos_found]

    progress_data = {}

    for (student, student_email_pair, escapejsed_student_email,
         user_exercise_graph) in izip(list_students, student_email_pairs,
                                      emails_escapejsed, user_exercise_graphs):

        student_email = student.email

        student_review_exercise_names = user_exercise_graph.review_exercise_names(
        )

        progress_data[student_email] = student_data = {
            'email': student.email,
            'nickname': student.nickname,
            'profile_root': student.profile_root,
            'exercises': [],
            'videos': [],
        }

        for (exercise, (_, exercise_display,
                        exercise_name_js)) in izip(exercises_found,
                                                   exercise_names):

            exercise_name = exercise.name
            graph_dict = user_exercise_graph.graph_dict(exercise_name)

            status = ""
            status_name = ""

            if graph_dict["proficient"]:
                if exercise_name in student_review_exercise_names:
                    status_name = "review"
                else:
                    if not graph_dict["explicitly_proficient"]:
                        status_name = "proficient_implicit"
                    else:
                        status_name = "proficient"
            elif graph_dict["struggling"]:
                status_name = "struggling"
            elif graph_dict["total_done"] > 0:
                status_name = "started"

            status = STATUSES[status_name]
            if status:
                student_data['exercises'].append({
                    "status":
                    status,
                    "status_name":
                    status_name,
                    "progress":
                    graph_dict["progress"],
                    "total_done":
                    graph_dict["total_done"],
                    "last_done":
                    graph_dict["last_done"] if graph_dict["last_done"]
                    and graph_dict["last_done"].year > 1 else '',
                    "last_done_ago":
                    timesince_ago(graph_dict["last_done"])
                    if graph_dict["last_done"]
                    and graph_dict["last_done"].year > 1 else ''
                })
            else:
                student_data['exercises'].append({
                    "name": exercise_name,
                    "status": status,
                })

        video_progress = all_video_progress[student]
        for video in videos_found:
            status_name = video_progress.get(video.key().id(), "")
            status = STATUSES[status_name]
            student_data['videos'].append({
                "name": video.title,
                "status": status,
                "status_name": status_name,
            })

    student_row_data = [data for key, data in progress_data.iteritems()]

    return {
        'exercise_names':
        exercise_list,
        'video_names':
        video_list,
        'progress_data':
        student_row_data,
        'coach_email':
        user_data.email,
        'c_points':
        reduce(lambda a, b: a + b, map(lambda s: s.points, list_students), 0)
    }
def class_progress_report_graph_context(user_data, list_students):
    if not user_data:
        return {}

    list_students = sorted(list_students, key=lambda student: student.nickname)

    student_email_pairs = [(escape(s.email), (s.nickname[:14] + '...') if len(s.nickname) > 17 else s.nickname) for s in list_students]
    emails_escapejsed = [escapejs(s.email) for s in list_students]

    exercises_all = Exercise.get_all_use_cache()
    user_exercise_graphs = UserExerciseGraph.get(list_students)

    exercises_found = []

    for exercise in exercises_all:
        for user_exercise_graph in user_exercise_graphs:
            graph_dict = user_exercise_graph.graph_dict(exercise.name)
            if graph_dict and graph_dict["total_done"]:
                exercises_found.append(exercise)
                break

    exercise_names = [(e.name, e.display_name, escapejs(e.name)) for e in exercises_found]
    exercise_list = [{'name': e.name, 'display_name': e.display_name} for e in exercises_found]

    exercise_data = {}

    for (student, student_email_pair, escapejsed_student_email, user_exercise_graph) in izip(list_students, student_email_pairs, emails_escapejsed, user_exercise_graphs):

        student_email = student.email

        student_review_exercise_names = user_exercise_graph.review_exercise_names()

        for (exercise, (_, exercise_display, exercise_name_js)) in izip(exercises_found, exercise_names):

            exercise_name = exercise.name
            graph_dict = user_exercise_graph.graph_dict(exercise_name)

            status = ""

            if graph_dict["proficient"]:

                if exercise_name in student_review_exercise_names:
                    status = "Review"
                else:
                    status = "Proficient"
                    if not graph_dict["explicitly_proficient"]:
                        status = "Proficient (due to proficiency in a more advanced module)"

            elif graph_dict["struggling"]:
                status = "Struggling"
            elif graph_dict["total_done"] > 0:
                status = "Started"

            if student_email not in exercise_data:
                exercise_data[student_email] = {
                    'email': student.email,
                    'nickname': student.nickname,
                    'exercises': []
                }

            if len(status) > 0:
                exercise_data[student_email]['exercises'].append({
                    "status": status,
                    "progress": graph_dict["progress"],
                    "total_done": graph_dict["total_done"],
                    "last_done": graph_dict["last_done"] if graph_dict["last_done"] and graph_dict["last_done"].year > 1 else '',
                    "last_done_ago": timesince_ago(graph_dict["last_done"]) if graph_dict["last_done"] and graph_dict["last_done"].year > 1 else ''
                })
            else:
                exercise_data[student_email]['exercises'].append({
                    "name": exercise_name,
                    "status": status,
                })

    student_row_data = [data for key, data in exercise_data.iteritems()]

    return {
        'exercise_names': exercise_list,
        'exercise_data': student_row_data,
        'coach_email': user_data.email,
        'c_points': reduce(lambda a, b: a + b, map(lambda s: s.points, list_students), 0)
    }
def class_progress_report_graph_context(user_data, list_students):
    if not user_data:
        return {}

    list_students = sorted(list_students, key=lambda student: student.nickname)

    student_email_pairs = [(escape(s.email), (s.nickname[:14] + '...') if len(s.nickname) > 17 else s.nickname) for s in list_students]
    emails_escapejsed = [escapejs(s.email) for s in list_students]

    exercises_all = Exercise.get_all_use_cache()
    user_exercise_graphs = UserExerciseGraph.get(list_students)

    exercises_found = []

    for exercise in exercises_all:
        for user_exercise_graph in user_exercise_graphs:
            graph_dict = user_exercise_graph.graph_dict(exercise.name)
            if graph_dict and graph_dict["total_done"]:
                exercises_found.append(exercise)
                break

    exercise_names = [(e.name, e.display_name, escapejs(e.name)) for e in exercises_found]
    exercise_list = [{'name': e.name, 'display_name': e.display_name} for e in exercises_found]

    videos_all = Video.get_all()
    all_video_progress = dict(zip(list_students, get_video_progress_for_students(list_students)))
    videos_found = reduce(set.union, all_video_progress.itervalues(), set())

    videos_found = [video for video in videos_all if video.key().id() in videos_found]
    video_list = [{'name': v.readable_id, 'display_name': v.title} for v in videos_found]

    progress_data = {}

    for (student, student_email_pair, escapejsed_student_email, user_exercise_graph) in izip(list_students, student_email_pairs, emails_escapejsed, user_exercise_graphs):

        student_email = student.email

        student_review_exercise_names = user_exercise_graph.review_exercise_names()

        progress_data[student_email] = student_data = {
            'email': student.email,
            'nickname': student.nickname,
            'profile_root': student.profile_root,
            'exercises': [],
            'videos': [],
        }

        for (exercise, (_, exercise_display, exercise_name_js)) in izip(exercises_found, exercise_names):

            exercise_name = exercise.name
            graph_dict = user_exercise_graph.graph_dict(exercise_name)

            status = ""
            status_name = ""

            if graph_dict["proficient"]:
                if exercise_name in student_review_exercise_names:
                    status_name = "review"
                else:
                    if not graph_dict["explicitly_proficient"]:
                        status_name = "proficient_implicit"
                    else:
                        status_name = "proficient"
            elif graph_dict["struggling"]:
                status_name = "struggling"
            elif graph_dict["total_done"] > 0:
                status_name = "started"

            status = STATUSES[status_name]
            if status:
                student_data['exercises'].append({
                    "status": status,
                    "status_name": status_name,
                    "progress": graph_dict["progress"],
                    "total_done": graph_dict["total_done"],
                    "last_done": graph_dict["last_done"] if graph_dict["last_done"] and graph_dict["last_done"].year > 1 else '',
                    "last_done_ago": timesince_ago(graph_dict["last_done"]) if graph_dict["last_done"] and graph_dict["last_done"].year > 1 else ''
                })
            else:
                student_data['exercises'].append({
                    "name": exercise_name,
                    "status": status,
                })

        video_progress = all_video_progress[student]
        for video in videos_found:
            status_name = video_progress.get(video.key().id(), "")
            status = STATUSES[status_name]
            student_data['videos'].append({
                    "name": video.title,
                    "status": status,
                    "status_name": status_name,
                })


    student_row_data = [data for key, data in progress_data.iteritems()]

    return {
        'exercise_names': exercise_list,
        'video_names': video_list,
        'progress_data': student_row_data,
        'coach_email': user_data.email,
        'c_points': reduce(lambda a, b: a + b, map(lambda s: s.points, list_students), 0)
    }
Beispiel #25
0
def get_bucket_size(num_buckets, bucket_index):
    num_exercises = len(Exercise.get_all_use_cache())
    bucket_rem = num_exercises % num_buckets
    return (num_exercises / num_buckets) + (1 if bucket_index < bucket_rem else 0)
Beispiel #26
0
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,
    }
Beispiel #27
0
 def get(self):
     number = self.request_int('num', len(Exercise.get_all_use_cache()))
     self.render_json(self.number_facts_for_geckboard_text(number))
Beispiel #28
0
def get_bucket_size(num_buckets, bucket_index):
    num_exercises = len(Exercise.get_all_use_cache())
    bucket_rem = num_exercises % num_buckets
    return (num_exercises /
            num_buckets) + (1 if bucket_index < bucket_rem else 0)
Beispiel #29
0
 def get(self):
     number = self.request_int('num', len(Exercise.get_all_use_cache()))
     self.render_json(self.number_facts_for_geckboard_text(number))