def get_top_ten_improvable_states(explorations): ranked_states = [] for exploration in explorations: for state_id in exploration.state_ids: state = exploration.get_state_by_id(state_id) state_key = '%s.%s' % (exploration.id, state.id) # Get count of how many times the state was hit event_key = get_event_key(STATS_ENUMS.state_hit, state_key) all_count = Counter.get_value_by_id(event_key) if all_count == 0: continue # Count the number of times the default rule was hit. event_key = get_event_key( STATS_ENUMS.rule_hit, '%s.Default' % state_key) default_count = Journal.get_value_count_by_id(event_key) journal = Journal.get(event_key, strict=False) if journal: top_default_answers = collections.Counter( journal.values).most_common(5) else: top_default_answers = [] # Count the number of times an answer was submitted, regardless # of which rule it hits. completed_count = 0 for handler in state.widget.handlers: for rule in handler.rules: rule_name = create_rule_name(rule) event_key = get_event_key( STATS_ENUMS.rule_hit, '%s.%s' % (state_key, rule_name)) completed_count += Journal.get_value_count_by_id( event_key) incomplete_count = all_count - completed_count state_rank, improve_type = 0, '' eligible_flags = [] default_rule = filter(lambda rule: rule.name == 'Default', state.widget.handlers[0].rules)[0] default_self_loop = default_rule.dest == state.id if float(default_count) / all_count > .2 and default_self_loop: eligible_flags.append({ 'rank': default_count, 'improve_type': IMPROVE_TYPE_DEFAULT}) if float(incomplete_count) / all_count > .2: eligible_flags.append({ 'rank': incomplete_count, 'improve_type': IMPROVE_TYPE_INCOMPLETE}) eligible_flags = sorted( eligible_flags, key=lambda flag: flag['rank'], reverse=True) if eligible_flags: state_rank = eligible_flags[0]['rank'] improve_type = eligible_flags[0]['improve_type'] ranked_states.append({ 'exp_id': exploration.id, 'exp_name': exploration.title, 'state_id': state.id, 'state_name': state.name, 'rank': state_rank, 'type': improve_type, 'top_default_answers': top_default_answers }) problem_states = sorted( [state for state in ranked_states if state['rank'] != 0], key=lambda state: state['rank'], reverse=True) return problem_states[:10]