示例#1
0
文件: blog.py 项目: susub31/foodflix
def favs():
    db = get_db()

    liked = get_liked(session.get('user_id'))
    disliked = get_disliked(session.get('user_id'))
    restrictions = get_restrictions(session.get('user_id'))

    ingredients = []

    if request.method == 'POST':
        try:
            respose = request.form['recipe_id']
            # Parse out the type of button pressed (like or dislike)
            vote = re.search('[a-z]+', respose).group()

            # Parse out the recipe id from the response
            recipe_id = re.search('[0-9]+', respose).group()

            if vote == 'like':
                # Unlike if you click the button and it's already liked
                if recipe_id in liked:
                    liked.remove(recipe_id)
                # Like the recipe
                else:
                    liked.append(recipe_id)

                    # Un-dislike if it is disliked
                    if recipe_id in disliked:
                        disliked.remove(recipe_id)
            else:
                # Un-dislike if you click the button and it's already disliked
                if recipe_id in disliked:
                    disliked.remove(recipe_id)
                # Dislike the recipe
                else:
                    disliked.append(recipe_id)

                    # Unlike if it is liked
                    if recipe_id in liked:
                        liked.remove(recipe_id)

            db.execute('UPDATE user ' 'SET liked=?', (','.join(liked), ))
            db.execute('UPDATE user ' 'SET disliked=?', (','.join(disliked), ))
            db.commit()
            return redirect(url_for('blog.favs'))

        except BadRequestKeyError:
            print('No recipe_id key')

    recipes = get_recipes(ingredients, restrictions, session.get('user_id'))
    return render_template('browse.html',
                           recipes=recipes,
                           liked=liked,
                           disliked=disliked,
                           keywords=ingredients,
                           restrictions=restrictions,
                           recipe_num=0)
示例#2
0
文件: blog.py 项目: susub31/foodflix
def browse():

    ### Get query arguments:
    # Recipe number:
    try:
        recipe_num = int(request.args['recipe_num'])
        if recipe_num < 0:
            recipe_num = 0
    except (ValueError, KeyError):
        recipe_num = 0

    # Ingredients:
    ingredients = []
    ingr_str = ''
    try:
        ingredients = request.args['ingredients'].split(
            ' ')  # get ingr as array
        ingredients = [
            ingr for ingr in ingredients if ingr != '' and ingr != ','
        ]  #remove empty and commas
        ingr_str = request.args['ingredients']
    except BadRequestKeyError:
        print('No Ingredients key')

    ### Get link to DB
    db = get_db()

    ### Get user info
    liked = get_liked(session.get('user_id'))
    disliked = get_disliked(session.get('user_id'))
    restrictions = get_restrictions(session.get('user_id'))

    if request.method == 'POST':
        try:
            respose = request.form['recipe_id']
            # Parse out the type of button pressed (like or dislike)
            vote = re.search('[a-z]+', respose).group()

            # Parse out the recipe id from the response
            recipe_id = re.search('[0-9]+', respose).group()

            if vote == 'like':
                # Unlike if you click the button and it's already liked
                if recipe_id in liked:
                    liked.remove(recipe_id)
                # Like the recipe
                else:
                    liked.append(recipe_id)

                    # Un-dislike if it is disliked
                    if recipe_id in disliked:
                        disliked.remove(recipe_id)
            else:
                # Un-dislike if you click the button and it's already disliked
                if recipe_id in disliked:
                    disliked.remove(recipe_id)
                # Dislike the recipe
                else:
                    disliked.append(recipe_id)

                    # Unlike if it is liked
                    if recipe_id in liked:
                        liked.remove(recipe_id)

            db.execute('UPDATE user ' 'SET liked=?', (','.join(liked), ))
            db.execute('UPDATE user ' 'SET disliked=?', (','.join(disliked), ))
            db.commit()
            return redirect(
                url_for('blog.browse',
                        _anchor=recipe_id,
                        recipe_num=recipe_num,
                        ingredients=ingr_str))

        except BadRequestKeyError:
            print('No recipe_id key')

    ### Finally get the recipes from DB
    recipes = get_recipes(ingredients, restrictions, '')
    recipes = recipes[recipe_num:recipe_num + 10]

    return render_template('browse.html',
                           recipes=recipes,
                           liked=liked,
                           disliked=disliked,
                           ingredients=ingredients,
                           ingr_str=ingr_str,
                           restrictions=restrictions,
                           recipe_num=recipe_num)
示例#3
0
文件: blog.py 项目: susub31/foodflix
def recommender():
    MIN_LIKED_RECIPES = 3

    # Connect to the database
    db = get_db()

    # Get data on what the user has liked so far
    user_query = db.execute('SELECT * ' 'FROM user ').fetchone()

    # Pull information on what the user likes to use in the engine
    try:
        liked_str = user_query['liked']
        liked = liked_str.split(',')
    except:
        liked = []

    if len(liked) < MIN_LIKED_RECIPES:
        flash(
            f'You need to like at least {MIN_LIKED_RECIPES} recipes to get '
            'recommendations', 'danger')
        recipes = []
        return render_template("browse.html", recipes=recipes)

    # Get any dietary restrictions to include in the recommendation
    restriction_query = db.execute('SELECT restrictions '
                                   'FROM user ').fetchone()

    restrictions = restriction_query['restrictions'].split()

    # Build the food recommender engine and train
    engine = FoodFlixEngine()
    engine.train(restrictions=restrictions)

    # Pull some recipe recommendations
    recipes = engine.predict(cals_per_day=user_query['cals_per_day'],
                             add_random=False)

    liked = get_liked(session.get('user_id'))
    disliked = get_disliked(session.get('user_id'))

    if request.method == 'POST':
        try:
            respose = request.form['recipe_id']
            # Parse out the type of button pressed (like or dislike)
            vote = re.search('[a-z]+', respose).group()

            # Parse out the recipe id from the response
            recipe_id = re.search('[0-9]+', respose).group()

            if vote == 'like':
                # Like the recipe
                liked.append(recipe_id)
            else:
                # Dislike the recipe
                disliked.append(recipe_id)

            db.execute('UPDATE user ' 'SET liked=?', (','.join(liked), ))
            db.execute('UPDATE user ' 'SET disliked=?', (','.join(disliked), ))
            db.commit()
            return redirect(url_for('blog.recommender'))

        except BadRequestKeyError:
            print('No recipe_id key')

    return render_template("browse.html", recipes=recipes, recipe_num=0)
示例#4
0
    def predict(self, cals_per_day, w_like=1.5, w_dislike=0.3, n_closest=4, add_random=False):
        """
        Generate predictions

        Parameters
        ==========
        cals_per_day : float
            Total recommended calories per day for a user.
        w_like : float
            Weighting for liked recipes in computing recommendations.
        w_dislike : float
            Weighting for disliked recipes in computing recommendations.
        n_closest : int
            Number of recommended recipes 
        add_random : bool
            Whether including a random suggestion for testing
        """
        # Divide the daily calories into five meals
        cals_per_day /= 5

        # Connect to the database to grab user information
        db = get_db()

        # Get liked and disliked recipes
        liked = get_liked(session.get('user_id'))
        disliked = get_disliked(session.get('user_id'))

        # The TF-IDF db uses recipe_id as the index as integers...
        # TODO kjb: make all recipe_id indices either string or integer
        liked = [int(l) for l in liked]
        disliked = [int(l) for l in disliked]

        # Grab the TF-IDF features to compute scores
        tfidf_query = 'SELECT * FROM tfidf;'
        tfidf = pd.read_sql(sql=tfidf_query, con=db, index_col='recipe_id')

        # Grab the feature vectors for the liked and disliked recipes
        likes = tfidf.loc[liked]
        dislikes = tfidf.loc[disliked]

        # Compute the Rocchio topic
        topic = self.compute_rocchio_topic(likes, dislikes, w_like, w_dislike)

        # Find recipes similar to the Rocchio topic
        similarity = cosine_similarity(np.atleast_2d(topic), tfidf)
        similarity = pd.Series(similarity[0], index=tfidf.index)

        recommendations = similarity.sort_values(ascending=False)
        recommendations = list(recommendations.index)

        # Create a container to hold recommended recipes
        recipes = []
        n_recs = 0
        for rec in recommendations:
            recipe_query = db.execute(
                'SELECT * '
                'FROM recipes '
                'WHERE recipe_id == ? ',
                (rec,)
            ).fetchone()

            # Only recommend things that you don't already like
            if recipe_query['recipe_id'] not in liked:

                recipe_dict = dict( recipe_query ) #convert to dict to allow addition of elements
                recipe_dict['generator'] = 'Recommender TF-IDF'
                # # Recommend only recipes around your cal/week goal
                # cals = int(recipe_query['calorie_count'].replace('cals',''))
                # if cals > cals_per_day * 0.8 and cals < cals_per_day * 1.2:
                recipes.append(recipe_dict)
                n_recs+=1

            if n_recs >= n_closest:
                break

        # Include random suggestion if enabled
        if add_random:
            # Get all recipes from DB
            all_recipes = get_recipes('','','')
            recipe_rand = dict( random.choice(all_recipes) )
            recipe_rand['generator'] = 'Random'
            recipes.append( recipe_rand )

        # Shuffle around
        random.shuffle(recipes)

        return recipes