def get_next_recommendations(user, request): """Get the recommendations for the Next section, and return them as a list. Logic: Next recommendations are currently comprised of 3 main subgroups: group recommendations, struggling exercises, and topic tree based data. Group recommendations consist of finding the most common item tackled immediately after the most recent item, struggling is determined by the "struggling" model attribute, and topic tree data is based off the graphical distance between neighboring exercise/topic nodes. Args: user -- The current user as a facility user model object. """ exercise_parents_table = get_exercise_parents_lookup_table() most_recent = get_most_recent_exercises(user) complete_exercises = set(get_completed_exercises(user)) def filter_complete(ex): return ex not in complete_exercises if len(most_recent) > 0 and most_recent[0] in exercise_parents_table: current_subtopic = exercise_parents_table[most_recent[0]]['subtopic_id'] else: current_subtopic = None #logic for recommendations based off of the topic tree structure if current_subtopic: topic_tree_based_data = generate_recommendation_data()[current_subtopic]['related_subtopics'][:settings.TOPIC_RECOMMENDATION_DEPTH] topic_tree_based_data = get_exercises_from_topics(topic_tree_based_data) else: topic_tree_based_data = [] #for checking that only exercises that have not been accessed are returned topic_tree_based_data = [ex for ex in topic_tree_based_data if ex not in most_recent or filter_complete(ex)] #logic to generate recommendations based on exercises student is struggling with struggling = filter(filter_complete, get_exercise_prereqs(get_struggling_exercises(user))) #logic to get recommendations based on group patterns, if applicable group = filter(filter_complete, get_group_recommendations(user)) #now append titles and other metadata to each exercise id final = [] # final data to return for exercise_id in (group[:2] + struggling[:2] + topic_tree_based_data[:1]): #notice the concatenation if exercise_id in exercise_parents_table: subtopic_id = exercise_parents_table[exercise_id]['subtopic_id'] exercise = get_exercise_data(request, exercise_id) exercise["topic"] = get_topic_data(request, subtopic_id) final.append(exercise) #final recommendations are a combination of struggling, group filtering, and topic_tree filtering return final
def get_explore_recommendations(user, request): """Get the recommendations for the Explore section, and return them as a list. Logic: Looks at a preset distance away, beginning at 2 to exclude self recommendations, to recommend a topic for exploration. Currently, the cap is a distance of 6 so that all recommendations will still be of moderate relatedness. This number is not permanent, and can be tweaked as needed. Args: user -- The current user as a facility user model object. """ data = generate_recommendation_data() #topic tree alg exercise_parents_table = get_exercise_parents_lookup_table() #for finding out subtopic ids recent_exercises = get_most_recent_exercises(user) #most recent ex #simply getting a list of subtopics accessed by user recent_subtopics = list(set([exercise_parents_table[ex]['subtopic_id'] for ex in recent_exercises if ex in exercise_parents_table])) #choose sample number, up to three sampleNum = min(len(recent_subtopics), settings.TOPIC_RECOMMENDATION_DEPTH) random_subtopics = random.sample(recent_subtopics, sampleNum) added = [] #keep track of what has been added (below) final = [] #final recommendations to return for subtopic_id in random_subtopics: related_subtopics = data[subtopic_id]['related_subtopics'][2:7] #get recommendations based on this, can tweak numbers! recommended_topic = next(topic for topic in related_subtopics if not topic in added and not topic in recent_subtopics) if recommended_topic: final.append({ 'suggested_topic': get_topic_data(request, recommended_topic), 'interest_topic': get_topic_data(request, subtopic_id), }) added.append(recommended_topic) return final
def get_explore_recommendations(user, request): """Get the recommendations for the Explore section, and return them as a list. Logic: Looks at a preset distance away, beginning at 2 to exclude self recommendations, to recommend a topic for exploration. Currently, the cap is a distance of 6 so that all recommendations will still be of moderate relatedness. This number is not permanent, and can be tweaked as needed. Args: user -- The current user as a facility user model object. """ data = generate_recommendation_data() #topic tree alg exercise_parents_table = get_exercise_parents_lookup_table() #for finding out subtopic ids recent_exercises = get_most_recent_exercises(user) #most recent ex #simply getting a list of subtopics accessed by user recent_subtopics = list(set([exercise_parents_table[ex]['subtopic_id'] for ex in recent_exercises if ex in exercise_parents_table])) #choose sample number, up to three sampleNum = min(len(recent_subtopics), settings.TOPIC_RECOMMENDATION_DEPTH) random_subtopics = random.sample(recent_subtopics, sampleNum) added = [] #keep track of what has been added (below) final = [] #final recommendations to return for subtopic_id in random_subtopics: related_subtopics = data[subtopic_id]['related_subtopics'][2:7] #get recommendations based on this, can tweak numbers! for topic in related_subtopics: if topic not in added and topic not in recent_subtopics: final.append({ 'suggested_topic': get_topic_data(request, topic), 'interest_topic': get_topic_data(request, subtopic_id), }) added.append(topic) return final