def index(): if request.method == 'POST': rating = request.form['rating'] recipe_id = request.form['recipe'] error = None if error is not None: flash(error) else: db = get_db() db.execute( 'INSERT INTO rating (recipe_id, user_id, rating)' ' VALUES (?, ?, ?)', (recipe_id, g.user['id'], rating)) db.commit() return redirect('/') else: db = get_db() recipe = db.execute( 'SELECT * FROM recipe r WHERE r.id' ' NOT IN (SELECT recipe_id FROM rating WHERE user_id = ?)' ' ORDER BY RANDOM() LIMIT 1', (g.user['id'], )).fetchone() recommendations = recommender.getRecommendations(g.user['id']) recommendation_ids = [x[1] for x in recommendations] recommendation_ids_sql = tuple(recommendation_ids) recommended_recipes = db.execute( 'SELECT * FROM recipe WHERE id IN {}'.format( recommendation_ids_sql)) return render_template('rating/index.html', recipe=recipe, recommendations=recommended_recipes)
def register(): if request.method == 'POST': email = request.form['email'] password = request.form['password'] db = get_db() error = None if not email: error = 'Email is required.' elif not password: error = 'Password is required.' elif db.execute( 'SELECT id FROM user WHERE email = ?', (email,) ).fetchone() is not None: error = 'User {} is already registered.'.format(email) if error is None: db.execute( 'INSERT INTO user (email, password) VALUES (?, ?)', (email, generate_password_hash(password)) ) db.commit() return redirect(url_for('auth.login')) flash(error) return render_template('auth/register.html')
def getRecommendations(person, similarity=sim_pearson): db = get_db() person = str(person) users = db.execute('SELECT id FROM user').fetchall() user_list = [str(x[0]) for x in users] reviews = dict( db.execute('SELECT recipe_id, rating FROM rating WHERE user_id = ?', person).fetchall()) totals = {} simSums = {} for other in user_list: if other == person: continue sim = similarity(person, other) if sim <= 0: continue other_reviews = dict( db.execute( 'SELECT recipe_id, rating FROM rating WHERE user_id = ?', other).fetchall()) for item in other_reviews: if item not in reviews or reviews[item] == 0: totals.setdefault(item, 0) totals[item] += other_reviews[item] * sim simSums.setdefault(item, 0) simSums[item] += sim rankings = [(total / simSums[item], item) for item, total in totals.items()] rankings.sort() rankings.reverse() return rankings
def load_logged_in_user(): user_id = session.get('user_id') if user_id is None: g.user = None else: g.user = get_db().execute( 'SELECT * FROM user WHERE id = ?', (user_id,) ).fetchone()
def topMatches(person, n=5, similarity=sim_pearson): db = get_db() users = db.execute('SELECT id FROM user').fetchall() user_list = [str(x[0]) for x in users] scores = [(similarity(person, other), other) for other in user_list if other != person] scores.sort() scores.reverse() return scores[0:n]
def sim_distance(p1, p2): db = get_db() p1reviews = dict( db.execute('SELECT recipe_id, rating FROM rating WHERE user_id = ?', p1).fetchall()) p2reviews = dict( db.execute('SELECT recipe_id, rating FROM rating WHERE user_id = ?', p2).fetchall()) si = {} for item in p1reviews: if item in p2reviews: si[item] = 1 if len(si) == 0: return 0 sum_of_squares = sum( [pow(p1reviews[item] - p2reviews[item], 2) for item in si]) return 1 / (1 + sqrt(sum_of_squares))
def login(): if request.method == 'POST': email = request.form['email'] password = request.form['password'] db = get_db() error = None user = db.execute( 'SELECT * FROM user WHERE email = ?', (email,) ).fetchone() if user is None: error = 'Incorrect email address.' elif not check_password_hash(user['password'], password): error = 'Incorrect password.' if error is None: session.clear() session['user_id'] = user['id'] return redirect(url_for('rating.index')) flash(error) return render_template('auth/login.html')
def sim_pearson(p1, p2): db = get_db() p1reviews = dict( db.execute('SELECT recipe_id, rating FROM rating WHERE user_id = ?', p1).fetchall()) p2reviews = dict( db.execute('SELECT recipe_id, rating FROM rating WHERE user_id = ?', p2).fetchall()) si = {} for item in p1reviews: if item in p2reviews: si[item] = 1 n = len(si) if n == 0: return 0 sum1 = sum([p1reviews[it] for it in si]) sum2 = sum([p2reviews[it] for it in si]) sum1Sq = sum([pow(p1reviews[it], 2) for it in si]) sum2Sq = sum([pow(p2reviews[it], 2) for it in si]) pSum = sum([p1reviews[it] * p2reviews[it] for it in si]) num = pSum - (sum1 * sum2 / n) den = sqrt((sum1Sq - pow(sum1, 2) / n) * (sum2Sq - pow(sum2, 2) / n)) if den == 0: return 0 r = num / den return r