健康的な食事のためのシンプルなサービスのプロトタイプ

画像







記事の文脈では、写真は二重の意味を帯びています。







免責事項



社会では、原則として、「正しい」食べ物、「ダイエット」、「ライフスタイル」などに関して「余分な」ことがたくさんあります。 原則として、これらは特定の地域の比較的高いレベルの給与と人々の間の低いレベルのリテラシーの単純な現れです。 私のガールフレンドと私は、おいしい、シンプル、安く、正しくて速い食事をするという、自分自身のための非常にシンプルなタスクを設定しました。







そして、そのような栄養を計画するためのツールを選択するとき、ホームサーバー上にあるPostgreSQLに視線が落ちました。 同様に、ExcelやGoogleのテーブルでも簡単に実行できますが、今回のケースではSQLの方が高速であることが判明し、既製のデータを含むオープンデータベースがあります。 この記事は、似たようなSQLサービスの「空白」として、または単に自分で考えて申請できるアイデアとみなすことができます。

また、注意を払ってください-これを最大限に活用するには、テーブルプロセッサ(Excel)で少なくとも少しできる必要があります。







記事の送信先のグループ:




記事を「行っていない」人々のグループ:




エントリー:



しばらくの間、私はモスクワに住んでいました。 モスクワ(私の世界では)は通常、次の特徴があります。







手頃な価格の食品の低品質または少し手頃な価格の高価格。

店からの一般的なゴム製品(少なくとも一度キプロスに行ったことがある場合-あなたは理解します);

努力せずに同時に正しく、安く、おいしい食事をする方法の欠如(あなたがまだ調理する必要がある50-60%のマージンを持つマーケティングサービスは言うまでもありません);

原則として、すべてが通常価格で利用できるが、生の形式の市場の存在。







せっかちな上級者向けのTLDR:





結果:



このため、私たちは自分用のミニサービスを作ることにしました。私たちは好きなシンプルな料理を作りました。 一般的に、私たちはUSDAベースを使用しようとしましたが、非常に複雑であることが判明しました。 このサービスのために、私たちは約10週間食料を購入しようとしましたが、経験から次のことがわかりました









一般的に、いつかはそのようなことアルゴリズムをアプリケーションと製品に変える方法の説明)に到達するかもしれませんが、これまでの同僚や市場とのコミュニケーションは、金持ちは料理をしないことを示唆しています(彼らはおそらくサービスに50-80%のマージンを支払うでしょう)、そして、ロシアの「貧しい」人は申請の費用を支払わないでしょう。







単純なカロリー最適化はなぜですか? なぜタンパク質ではないのですか?



それは機能しますが、ニーズの理想的な測定のためのメカニズムはまだありません(または、私たちはそれを知りません)。







get_random_menu()関数は、カロリー、タンパク質、炭水化物の理想的な摂取量も提供します-手で比較できます。 Pythonで線形および非線形最適化アルゴリズムを使用しようとしました(10,000個のメニューをランダムに生成し、「完璧な」フィットのために重みを改善しようとしましたが、1、2時間で結果を達成できませんでした)、ほとんどの場合、料理のセットがあまりありません100%ヒットする可能性があります-タンパク質と炭水化物は、「理想」よりも平均で15〜20%少なくなります。







技術コンポーネント、ベース、機能の説明:



一般に、データ構造への入力と関数の書き込みには、テーブルで約3〜4時間、関数で2〜3時間かかり、ERスキームでうまく表現されています。







画像







以下に注意してください。









人々のニーズを説明する2つの表もありますが、人々の数を変えるにはそれらの修正が必要です







画像







(SQLを知っている場合)を理解する最も簡単な方法は、いくつかの基本的な関数を見ることによって、すべてがどのように機能するかです。



getPrimitiveMenu









 CREATE OR REPLACE FUNCTION "usda28"."getPrimitiveMenu"() RETURNS SETOF "pg_catalog"."record" AS $BODY$ BEGIN RETURN QUERY SELECT raw_data1.week_day ::INTEGER as week_day, raw_data1.meal_order :: INTEGER as meal_id, raw_data1.meal :: VARCHAR as meal, raw_data1.balance ::NUMERIC as dish_share, raw_data1.dish_type :: VARCHAR as dish_type, d.title :: VARCHAR as dish_title, d.deliciousness :: INTEGER as dish_taste, dc.portion :: NUMERIC as proportion, di.id::INTEGER as dish_ingredient_id, di.title ::VARCHAR as di_title, di.calories :: INTEGER as calories_per_100, di.carbs :: INTEGER as carbs_per_100, di.fat :: INTEGER as fat_per_100, di.protein :: INTEGER as protein_per_100 FROM ( SELECT dsc.calorie_balance as balance, ds.title as meal, dsc.dish_serving_id, dsc.choice_id, ds.id as meal_order, dt.title as dish_type, presets.week_day as week_day, ( SELECT d."id" FROM usda28.dish d /* Checking that the dish has actual ingredients, otherwise errors are possible */ JOIN usda28.dish_contents dc ON dc.dish_id = d."id" WHERE d.dish_type_id = dsc.dish_type_id ORDER BY random() LIMIT 1 ) as dish_id FROM ( SELECT servings_count.dsc_id as dsc_id, trunc(servings_count.choice_count * random() + 1)::INTEGER as preset_choice, unnest(ARRAY[1,2,3,4,5,6,7]) as week_day FROM ( SELECT DISTINCT dsc.dish_serving_id as dsc_id, COUNT(DISTINCT dsc.choice_id) as choice_count FROM usda28.dish_serving_choice dsc GROUP BY dsc.dish_serving_id ) servings_count ORDER BY unnest(ARRAY[1,2,3,4,5,6,7]) ) presets JOIN usda28.dish_serving_choice dsc ON dsc.choice_id = presets.preset_choice AND dsc.dish_serving_id = presets.dsc_id JOIN usda28.dish_serving ds ON ds."id" = dsc.dish_serving_id JOIN usda28.dish_type dt ON dt."id" = dsc.dish_type_id ORDER BY presets.week_day ASC, dsc.dish_serving_id ASC ) raw_data1 JOIN usda28.dish d ON d."id" = raw_data1.dish_id JOIN usda28.dish_contents dc ON dc.dish_id = d."id" JOIN usda28.dish_ingredient di ON di."id" = dc.ingredient_id ORDER BY raw_data1.week_day ASC, raw_data1.meal_order ASC, d.title ASC; END $BODY$ LANGUAGE 'plpgsql' VOLATILE COST 100 ROWS 1000 ;
      
      





get_random_menu









 CREATE OR REPLACE FUNCTION "usda28"."get_random_menu"() RETURNS "pg_catalog"."json" AS $BODY$ SELECT to_json(array_agg(a)) FROM ( SELECT (SELECT md5(''||now()::text||random()::text) as menu_uuid), raw_data.week_day as week_day, raw_data.meal_id as meal_id, raw_data.meal as meal, raw_data.dish_type as dish_type, raw_data.dish_title as dish_title, raw_data.dish_ingredient_id as dish_ingredient_id, raw_data.ingredient_title as ingredient_title, raw_data.dish_share, raw_data.proportion, raw_data.calories_per_100, raw_data.carbs_per_100, raw_data.fat_per_100, raw_data.protein_per_100, trunc( raw_data.proportion * raw_data.dish_share * raw_data.calories * 100 / SUM(raw_data.stat_weight) OVER (PARTITION BY raw_data.week_day, raw_data.meal_id, raw_data.meal, raw_data.dish_type, raw_data.dish_title ) )as grams_guesstimate FROM ( SELECT menu.week_day as week_day, menu.meal_id as meal_id, menu.meal as meal, menu.dish_type as dish_type, menu.dish_title as dish_title, menu.dish_ingredient_id as dish_ingredient_id, menu.di_title as ingredient_title, menu.dish_share, menu.proportion, menu.calories_per_100, menu.carbs_per_100, menu.fat_per_100, menu.protein_per_100, nut.calories, menu.proportion * menu.calories_per_100 as stat_weight FROM ( SELECT week_day, meal_id, meal, dish_share, dish_type, dish_title, dish_taste, proportion, dish_ingredient_id, di_title, calories_per_100, carbs_per_100, fat_per_100, protein_per_100 FROM usda28."getPrimitiveMenu"() ) menu JOIN ( SELECT SUM (rdi.carbs) * mlp.proportion as carbs, SUM (rdi.fat) * mlp.proportion as fat, SUM (rdi.protein) * mlp.proportion as protein, SUM (rdi.calories) * mlp.proportion as calories, ml.title as meal_title, ml."id" as meal_id FROM usda28.recommended_daily_intake rdi JOIN usda28.activity_types atp ON atp."id" = rdi.activity_type_id AND atp."id" = 1 JOIN usda28.meal_proportions mlp ON 1=1 JOIN usda28.dish_serving ml ON ml.id = mlp.meal_id GROUP BY ml.title, mlp.proportion, ml."id" ) nut ON nut.meal_id = menu.meal_id ) raw_data ORDER BY raw_data.meal_id ASC, raw_data.week_day ASC, raw_data.dish_type ASC ) a $BODY$ LANGUAGE 'sql' VOLATILE COST 100 ;
      
      





あなたがそれを好めば-個人的に書きなさい。








All Articles