class Favorite(Resource): def __init__(self): self.builder = RestaurantBuilder() self.engine = sql.create_engine('sqlite:///database.db', echo=True) self.connection = self.engine.connect() def add(self): query = self.query(Query.add_favorite.value) params = {"client_id": request.json['client_id'], "restaurant_id": request.json['restaurant_id']} self.request(query, params) query = self.query(Query.favorites.value) params = {"client_id": request.json['client_id']} data = self.request(query, params) if 'error' in data: return jsonify(data) else: return self.builder.restaurants(data) def remove(self): query = self.query(Query.remove_favorite.value) params = {"client_id": request.args.get('client_id'), "restaurant_id": request.args.get('restaurant_id')} self.request(query, params) query = self.query(Query.favorites.value) params = {"client_id": request.args.get('client_id')} data = self.request(query, params) if 'error' in data: return jsonify(data) else: return self.builder.restaurants(data) def list(self): query = self.query(Query.favorites.value) params = {"client_id": request.args.get('client_id')} data = self.request(query, params) if 'error' in data: return jsonify(data) else: return self.builder.restaurants(data) def query(self, file): fd = open(file, 'r') query = fd.read() fd.close() return query def request(self, query, params=None): try: data = self.connection.execute(query, params) if data.cursor is not None: return [dict(zip(tuple(data.keys()), i)) for i in data.cursor] except exc.SQLAlchemyError as error: return {'error': {'code': error.code, 'message': error.orig.args[0]}}
def __init__(self): self.builder = RestaurantBuilder() self.engine = sql.create_engine('sqlite:///database.db') self.connection = self.engine.connect()
class Recommendation(Resource): def __init__(self): self.builder = RestaurantBuilder() self.engine = sql.create_engine('sqlite:///database.db', echo=True) self.connection = self.engine.connect() def by_onboarding(self): onboarding = self.onboarding(request) if onboarding.empty: return jsonify({'data': []}) restaurants = self.restaurants(request) columns = [ 'id', 'average_cost', 'average_rating', 'chairs', 'cuisine_id', 'moment_id' ] restaurants = restaurants[columns] if restaurants.empty: return jsonify({'data': []}) recommended = self.k_means_round(onboarding, restaurants) recommendations = self.recommendations(tuple(recommended)) return recommendations def by_preferences(self): preferences = self.preferences(request) if preferences.empty: return jsonify({'data': []}) restaurants = self.restaurants(request) if restaurants.empty: return jsonify({'data': []}) recommended = self.k_means_round(preferences, restaurants) recommended.append(preferences['id']) recommendations = self.recommendations(tuple(recommended)) return recommendations def by_usages(self): usages = self.usages(request) if usages.empty: return jsonify({'data': []}) restaurants = self.restaurants(request) if restaurants.empty: return jsonify({'data': []}) recommended = self.k_means_round(usages, restaurants) recommendations = self.recommendations(tuple(recommended)) return recommendations def by_favorites(self): favorites = self.favorites(request) if favorites.empty: return jsonify({'data': []}) restaurants = self.restaurants(request) if restaurants.empty: return jsonify({'data': []}) recommended = self.k_means_round(favorites, restaurants) recommendations = self.recommendations(tuple(recommended)) return recommendations def k_means_round(self, personal, restaurants): personal_features = self.features(personal) restaurants_features = self.features(restaurants) data_frame = personal_features.append(restaurants_features) normalized = self.normalize(data_frame) base = normalized.iloc[:len(personal)] training = normalized.iloc[len(personal):] n_clusters = self.elbow(training) try: recommended = self.k_means(base, training, n_clusters) restaurants = restaurants.loc[recommended].reset_index(drop=True) if len(restaurants) <= 50 or n_clusters <= 1: return restaurants['id'] return self.k_means_round(personal, restaurants) except: return restaurants['id'] def k_means(self, base, training, n_clusters): k_means = KMeans(n_clusters=n_clusters, init='k-means++') k_means = k_means.fit(training) predict = k_means.predict(base) n_cluster = coll.Counter(predict).most_common(1).pop() return np.where(k_means.labels_ == n_cluster[0])[0] def features(self, data_frame): return data_frame[data_frame.columns.difference(['id', 'offer_id'])] def normalize(self, data_frame): scale = preprocessing.MinMaxScaler() normalized = scale.fit_transform(data_frame.values) normalized_data_frame = pd.DataFrame(normalized) normalized_data_frame.columns = data_frame.columns return normalized_data_frame def elbow(self, features): size = list(range(1, len(features.columns))) variations = [] for clusters in size: k_means = KMeans(n_clusters=clusters, init='random') k_means.fit(features) variations.append(k_means.inertia_) average = np.average(variations) variations = list( filter(lambda variation: variation > average, variations)) return len(variations) + 1 def onboarding(self, request): data = [{ 'id': 0, 'average_cost': request.args.get('price'), 'average_rating': request.args.get('rating'), 'chairs': request.args.get('chairs'), 'cuisine_id': request.args.get('cuisine'), 'moment_id': request.args.get('moment') }] return pd.DataFrame(data) def preferences(self, request): query = self.query(PrivateQuery.preferences.value) params = {"client_id": request.args.get('client_id'), "like": 1} data = self.request(query, params) return pd.DataFrame(data) def usages(self, request): query = self.query(PrivateQuery.usages.value) params = {"client_id": request.args.get('client_id')} data = self.request(query, params) return pd.DataFrame(data) def favorites(self, request): query = self.query(PrivateQuery.favorites.value) params = {"client_id": request.args.get('client_id')} data = self.request(query, params) return pd.DataFrame(data) def restaurants(self, request): query = self.query(PrivateQuery.restaurants.value) params = { "city_id": request.args.get('city_id'), "client_id": request.args.get('client_id') } data = self.request(query, params) return pd.DataFrame(data) def recommendations(self, ids): query = self.query(Query.recommendations.value).replace( ':ids', str(ids)) data = self.request(query, {}) return self.builder.restaurants(data) def query(self, file): fd = open(file, 'r') query = fd.read() fd.close() return query def request(self, query, params=None): try: data = self.connection.execute(query, params) if data.cursor is not None: return [dict(zip(tuple(data.keys()), i)) for i in data.cursor] except exc.SQLAlchemyError as error: return { 'error': { 'code': error.code, 'message': error.orig.args[0] } }