• Главная
  • Контакты
Подписаться:
  • Twitter
  • Facebook
  • RSS
  • VK
  • PushAll
logo

logo

  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • За год
    • Положительные
    • Отрицательные
  • Сортировка
    • По дате (возр)
    • По дате (убыв)
    • По рейтингу (возр)
    • По рейтингу (убыв)
    • По комментам (возр)
    • По комментам (убыв)
    • По просмотрам (возр)
    • По просмотрам (убыв)
Главная
  • Все
    • Положительные
    • Отрицательные
  • За сегодня
    • Положительные
    • Отрицательные
  • За вчера
    • Положительные
    • Отрицательные
  • За 3 дня
    • Положительные
    • Отрицательные
  • За неделю
    • Положительные
    • Отрицательные
  • За месяц
    • Положительные
    • Отрицательные
  • Главная
  • Прототип простого сервиса для здорового питания

Прототип простого сервиса для здорового питания +2

24.04.2017 13:15
snakers4 7 3600 Источник
Разработка мобильных приложений*, Разработка веб-сайтов*, PostgreSQL*

image


В контексте статьи картинка обретает двойной смысл.


Дисклеймер


В обществе в принципе много "наносного" касательно "правильной" еды, "диет", "стиля жизни" и прочего. Как правило это просто проявления относительно высокого уровня зарплат в конкретном регионе и низкого уровня грамотности людей. Мы с моей девушкой поставили для себя очень простую задачу — есть вкусно, просто, дешево, правильно и быстро.


И так получилось, что при выборе инструмента планирования такого питания взор пал на PostgreSQL, который стоит на домашнем сервере. Аналогично можно легко сделать и в Excel или Гугл-таблицах, но в нашем случае SQL оказался более быстрым + есть открытые базы с готовыми данными. Данная статья может рассматриваться вами как "заготовка" для аналогичного SQL сервиса или просто как идея, которую вы можете взять и применить для себя.
Также обратите внимание — чтобы пользоваться этим в полной мере, вы должны хотя бы чуточку уметь в табличные процессоры (Excel).


Группы людей, которым "зайдет" статья:

  • Люди, которые знают SQL хотя бы на уровне простейших запросов (если вы DBA — некоторые упрощения здесь сделаны для экономии времени, а не по той причине, о которой вы подумали) ;
  • Люди, которые хотят контролировать что они едят;
  • Люди, которые хотят есть вкусно, недорого, просто и полезно;
  • Люди, которые хотят попробовать поковыряться в SQL-сервере или просто уверены в использовании этого инструмента;

Группы людей, которым не "зайдет" статья:

  • Почему функция возвращает просто запрос? Надо в 100 раз сложнее!
  • Так схемы делают только… / я ем все что попало / зачем SQL — давайте вообще монгу / кто так форматирует запросы итд;
  • Готовить — не барское дело!
  • Надо все нормализовать еще на 10 рядов!

Вступление:


Так уж получилось, что некоторое время я жил в Москве. Москва (в моем мире), как правило, характеризуется:


Низким качеством доступного питания или высокой ценой чуть менее доступного;
Общей резиновостью продуктов из магазина (если вы были на Кипре хоть раз — вы поймете);
Отсутствием способов питаться одновременно и правильно, и дешево и вкусно не прилагая усилий (не говорю про маркетинговые сервисы с маржинальностью в 50-60%, где все равно надо готовить);
Наличием рынков, где в принципе все доступно по нормальным ценам, но в "сыром" виде;


TLDR для нетерпеливых и продвинутых:


  • Скачайте себе дамп базы PostgreSQL (9.5+) базы по ссылке и распакуйте;
  • Если устраивают пресеты, которые есть, то просто вбейте запрос:
    SELECT
    *
    FROM
    get_random_menu()
  • Запрос отдаст вам json (если вы дочитали до сюда, то вы легко поменяете на нужный вам формат или дернете запрос каким-нибудь драйвером) с меню на неделю (7 дней) из расчета:
  • 2 взрослых человека — мужчина и женщина (recommended_daily_intake);
  • Расчет количества еды — просто экстраполяцией через калорийность (почему — описано ниже);
    • Питание 4 раза в сутки

    • Завтрак из нескольких блюд;

    • Обед;

    • Ужин;

    • Перекус вечером;

  • Меню выбирается случайно при каждом запросе;
  • Если не устраивают пресеты или нужно поменять количество людей (тут установлено для мужчины и женщины со средними потребностями):
  • Функция get_random_menu() подскажет, что поменять;
  • Основные таблицы, которые стоит подстраиваться под себя
    • recommended_daily_intake;

    • Все таблицы, содержащие слово dish;

    • Структура немного сложная, но она станет понятной, если вы почитаете запросы;


Результат:


По этой причине мы решили сделать мини-сервис для себя, куда мы внесли простые блюда которые нам нравятся. Вообще мы пробовали работать с базой USDA — но она оказалась избыточно сложной. По такому сервису мы попробовали покупать еду в течение ~ 10 недель, и выяснили по опыту, что:


  • В алгоритме были разные баги с пропорциями, которые мы поправили (15 килограмм квашеной капусты в неделю это сильно);
  • В среднем в неделю на 2 человек уходит порядка 4 000 рублей (!) + 1.5-2 часа на покупку + 30-40 минут на готовку вдвоем ежедневно. В месяц получается в районе 8 000-10 000 рублей на человека;
  • Девушка еще и значительно похудела (приятный бонус);
  • Оба перестали тратить деньги на покупку пищи вообще. И на обеды тоже;
  • Самый удобный формат работы с базой — выгрузил через любую доступную программу в таблицу, сделал сводную таблицу, залил на телефон;
  • Отмечать готовку блюд проще всего с телефона / компьютера в таблице;
  • Простая и вкусная еда и огромная экономия времени на планировании (10 часов макс. на разработку этого позволяет жить почти 3 месяца не думая про еду);

Вообще, может когда-нибудь руки дойдут и до такого (описание как превратить алгоритм в приложение и продукт), но пока общение с коллегами и рынок подсказывают, что "богатые" готовить не будут (скорее заплатят маржу в 50-80% сервисам), а "бедные" в России — не будут платить за приложение.


Почему "наивная" оптимизация по калориям? Почему не по белкам?


Потому, что работает, а механизма идеального измерения потребностей все равно нет (или мы его не знаем).


Функция get_random_menu() также отдает идеальное потребление калорий, белков и углеводов — вы можете сравнивать руками. Я пробовал применять алгоритмы линейной и нелинейной оптимизации в Питоне (сгенерировал 10,000 меню случайно, попробовал улучшать веса для "идеальной" подгонки, за час-два не добился результата, оставил), но скорее всего из-за нашего набора блюд там в принципе не особо возможно иметь 100% попадание — белков и углеводов в среднем меньше на 15-20% чем "идеал".


Описание технической составляющей, базы и функций:


В общем заполнение структуры данных и написание функций заняло примерно 3-4 часа на таблицы и 2-3 часа на функции и хорошо выражается ER схемой:


image


Обратите внимание на то, что:


  • Лучше использовать PostgreSQL 9.5+, т.к. используется несколько функции по работе с json, которые не так давно появились;
  • Есть понятие блюда (dish), есть понятие того в рамках каких приемов пищи оно может приниматься (dish_serving_choice, dish_serving);
  • dish_menu — пример лога купленной пищи, потом оказалось проще собирать в экселе;
  • Не каждое блюдо можно есть, скажем, на завтрак для этого есть dish_type;
  • Блюда состоят из ингредиентов (dish_ingredient), но не содержат воды (в ней нет калорий — оптимизация не сработает) — все пропорции посчитаны с учетом этого факта;
  • Мы приняли по сути несколько предположений:
  • Пропорции приема калорий в рамках приемов пищи (dish_serving_choice);
  • Требуемая калорийность (ниже);
  • Состав блюд (dish_contents);

Также есть 2 таблицы с описанием потребностей людей, их модификация требуется для изменения числа людей


image


Проще всего понять (если вы знаете SQL) как это все работает посмотрев на пару основных функций


getPrimitiveMenu


  • Базовая функция. которая просто создает случайное меню;
  • Создает случайное меню на 7 дней;
  • Рандомизация по сути делается через ORDER BY random();
  • Неделю мы создаем простой конструкцией unnest(ARRAY[1,2,3,4,5,6,7]);
  • Остальное — тривиально;

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


  • Функция, которая взвешивает меню по калориям и отдает случайное меню;
  • Если не знаете про window functions — почитайте;
  • По сути функция берет то, что сделала предыдущая функция + считает количество калорий подзапросом (… ) nut;
  • Условно сложная формула по сути является просто школьной пропорцией;

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
;

Если понравилось — пишите в личку.

Поделиться с друзьями
-->

Комментарии (7)


  1. PapaBubaDiop
    24.04.2017 17:17
    #10188930

    … поставили для себя очень простую задачу — есть вкусно, просто, дешево, правильно и быстро!

    Быстро не стыкуется с древней чехословацкой поговоркой:

    кто медленно жует, тот долго проживет.


    1. snakers4
      24.04.2017 19:57
      #10189124

      Быстро = быстро покупать и не тратить время на организацию процесса, а не быстро жевать =)


      1. PapaBubaDiop
        24.04.2017 20:34
        #10189174

        Для меня субботний поход на рынок за едой — процесс, полный удовольствия. Тайно признаюсь — это восхитительней, чем поход в музей)


        1. snakers4
          24.04.2017 20:57
          #10189208

          Вот и пообщались на IT-сайте про еду xDDD


          1. Vladal
            25.04.2017 17:02
            #10190682

            Как пропатчить…?


            1. snakers4
              25.04.2017 17:02
              #10190684

              У вас проблема с открытием дампа?


              1. Vladal
                26.04.2017 09:23
                #10191404

                Уже разобрался. Извините.

МЕТКИ

  • Хабы
  • Теги

Разработка мобильных приложений

Разработка веб-сайтов

PostgreSQL

postgresql

здоровый образ жизни

веб-сервисы

запросы к бд

прекрасное

СЕРВИСЫ
  • logo

    CloudLogs.ru - Облачное логирование

    • Храните логи вашего сервиса или приложения в облаке. Удобно просматривайте и анализируйте их.
Все публикации автора
  • Очень грубый подход к определению языка человека (или как понять язык человека по обычной корпоративной базе) +5

    • 12.06.2017 18:24

    Нейрокурятник: часть 4 — итоговая модель и код на прод +38

    • 12.06.2017 18:22

    Нейрокурятник часть 3. Про разметку кур +23

    • 12.06.2017 18:22

    Карта артистов, неуклюжий поиск связей в данных и как можно изобрести велосипед +10

    • 24.05.2017 04:16

    Нейрокурятник часть 2: про бота, который постит фотографии +18

    • 18.05.2017 03:34

    Платежные странички и решения (или через тернии к звездам — и через много картинок) +14

    • 17.05.2017 04:35

    Нейрокурятник ч.0. Или нейро- без курятника +18

    • 08.05.2017 04:45

    Нейрокурятник: часть 1. Установка Raspberry Pi и камеры в курятник и их настройка +35

    • 04.05.2017 02:39

    Прототип простого сервиса для здорового питания +2

    • 24.04.2017 13:15

Подписка


ЛУЧШЕЕ

  • Сегодня
  • Вчера
  • Позавчера
07:00

Нейро сети для самых маленьких. Часть первая (которая после нулевой). Удобство в прокрустовом ложе оптимизации +27

07:52

«Гражданин, обновитесь»: анализ вредоносной кампании Falcon +24

08:30

Хватит прятать ключи под ковром: переносим их в облачный сервис управления ключами (KMS) +21

08:11

Не только красные и синие — новые серверные процессоры от Qualcomm и Hygon +20

07:00

Сегментация опухолей головного мозга на МРТ-снимках с акцентом на точность границы +19

06:52

Работодатели давно играют в волков. Просто теперь соискатели научились отвечать +19

06:31

Лучший способ изучить разработку с Qt +16

09:40

Как вайбкодинг довел меня до депрессии, а потом привел к вайб‑инжинирингу +15

08:00

Кастомизация Битрикс24 на платформе Вайбкод: создаём паспорт клиента +15

07:06

Клод Шеннон. Информатика на максималках +15

11:01

Как установить Hermes на VPS. Один из лучших агентов в 2026 году +12

08:57

TPC-DS в 07.2026. Lakehouse: Spark, Trino, StarRocks, Impala и Doris. Greenplum & Cloudberry vs StarRocks как MPP +10

07:35

Контекстная инженерия для слабой локальной модели: как мы делаем среднюю модель надёжной +10

08:20

Навигация в Jetpack Compose без магии: что на самом деле делают библиотеки навигации +8

07:01

Автомобильные сигнализации РФ и их безопасность. Часть 1 +8

08:49

Не Bluetooth, а Wi-Fi: третья версия моей мощной портативной Hi-Fi акустики +7

07:00

Go vs GoF: положите паттерны ООП на пол и отойдите +7

08:11

65 бесплатных уроков июля: от LLM и RAG до Kubernetes, Go и QA +6

08:10

Совет требует ИИ, а данные не готовы. Как ESM даёт фундамент, который не провалит пилот +6

08:10

Машинное зрение: патенты в мире и в России +6

08:32

Что такое парадокс изогнутой трубы — и почему интуиция нас подводит +169

10:05

Почему я ухожу из Timeweb Cloud: 46 часов простоя в Амстердаме за два месяца — по данным самого хостера +96

12:00

Пузырь ИИ лопнул? Бизнес отказывается от ChatGPT, а Microsoft пытается спасти положение софтом: ML-дайджест +58

12:30

Passkey без Apple, Google и облаков: делаем собственный аппаратный ключ за 4 евро +55

18:44

PostgreSQL для бэкендера: 10 фич, которыми мало пользуются, а зря +51

09:02

Почему cron — самый опасный инструмент в Linux +48

07:03

Почтовый ящик пандоры. Какие сервисы работают с внешними почтовыми клиентами в России в 2026 году +35

13:01

Flappy Bird: делаем игру сложнее и добавляем автопилот на чистой математике +34

14:42

Почему сгорел Нотр-Дам: человеческий фактор, SHERPA и HTA в UX-проектировании интерфейса +29

07:05

kafkactl — другой взгляд на работу с Kafka +29

07:04

Умеют ли трансформеры водить машину +28

07:01

Шахматная память: как гроссмейстеры запоминают тысячи партий и почему это не мнемотехника +28

17:57

Антенный ротатор на PTZ 3050DZ +24

09:17

Почему опасно покупать Intel Core i7 и i9 с рук: разбираемся с деградацией процессоров 13900K и 14900K +23

09:09

Проектируем с нуля калькулятор на FPGA. Часть 6: CPU +23

08:01

Распределённый монолит: как одну проблему превратить в целый кластер проблем +21

14:27

Я больше не объясняю нейросети контекст. Вот что я сделал вместо этого… +18

10:26

Я декомпилировал свою зависимость: как программист раскидал курение на 100+ субличностей и перестал курить +17

08:00

Как мы реализовали оптимальное обучение CV-моделей в Luna Line. Часть 2. Сегментация +17

10:13

Бездумное использование ИИ ведёт к вырождению специалистов +16

15:10

Народная карта бензина собрала почти 2 млн посетителей за три дня. Её навайбкодил один человек +109

05:26

Как Яндекс меня кинул на фестивале для будущих яндексоидов, или Хроники одного YoungCon +62

07:01

Манипуляция ответами нейронок — как сеошники убивают интернет +59

05:05

Как одна операция из линейной алгебры захватила мир ИИ +55

07:59

Как мы работаем со студентами: дипломы, которые становятся частью YDB +46

07:59

Как мы работаем со студентами: дипломы, которые становятся частью YDB +46

11:13

Айсберг Доменов Верхнего Уровня (ICANN и не только) +44

07:05

Размагничивание кораблей: мины, физика и Курчатов. Часть 2 +43

11:12

Event Sourcing в платформе данных: миграция с JSON на Avro +42

09:01

TeamPCP: как команда хакеров-любителей «Дюны» закинула в наши Node.js-пакеты червей Shai-Hulud +42

21:02

Рунет без Google Login: что теперь делать с авторизацией +38

13:01

Триллионы километров данных: ваш автомобиль следит за вами, и это только начало +36

06:00

Человек-легенда, давший нам Спектрум и предсказавший ИИ +34

11:19

Как я переехал с Altium Designer на KiCAD +33

07:06

Семь раз подумай, один раз пошардируй: как мы начали горизонтально масштабировать метаданные чатов Телемоста +33

08:09

Обзор необычного и очень мощного мини-ПК Khadas Mind 2 +31

17:14

Что на самом деле означают теоремы Гёделя о неполноте? +27

15:05

И снова самый быстрый парсер JSON. Очередной +27

18:13

Как «ужать» мегаполис до размеров iPhone 4 +25

06:28

Забор из волшебных палочек +24

ОБСУЖДАЕМОЕ

  • Народная карта бензина собрала почти 2 млн посетителей за три дня. Её навайбкодил один человек +109

    • 199   45000

    Почему я ухожу из Timeweb Cloud: 46 часов простоя в Амстердаме за два месяца — по данным самого хостера +96

    • 151   22000

    Рунет без Google Login: что теперь делать с авторизацией +38

    • 136   25000

    Кажется я выяснил кто открыл Америку -9

    • 119   11000

    Что такое парадокс изогнутой трубы — и почему интуиция нас подводит +169

    • 84   26000

    Что лучше — C++ или C#? +6

    • 67   9600

    Как Let's Encrypt, только роднее: автоматическое получение бесплатного RSA DV-сертификата НУЦ +19

    • 59   11000

    Что на самом деле означают теоремы Гёделя о неполноте? +27

    • 57   14000

    Дело на вечер: собираем домашний ИИ-сервер +17

    • 54   17000

    Почему Минобрнауки боится ИИ и правда ли, что дипломные работы утратили смысл? +7

    • 39   12000

    Почтовый ящик пандоры. Какие сервисы работают с внешними почтовыми клиентами в России в 2026 году +35

    • 39   9800

    И все‑таки самая реальная защита дома или квартиры — электронно‑механический шлюз -10

    • 39   8500

    Почему «удалёнка» съедает ROI компании: расчёты потерь -1

    • 32   11000

    Passkey без Apple, Google и облаков: делаем собственный аппаратный ключ за 4 евро +55

    • 31   15000

    Отрежьте мне миллиард символов: как C++20, string_view и шаблонный ад могут скрывать баг годами +19

    • 31   11000
  • Главная
  • Контакты
© 2026. Все публикации принадлежат авторам.