<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Alexey Dubovskoy</title>
    <description>The latest articles on DEV Community by Alexey Dubovskoy (@dubadub).</description>
    <link>https://dev.to/dubadub</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F194777%2Fe9729089-09b5-4103-aa48-c43333d81c23.jpeg</url>
      <title>DEV Community: Alexey Dubovskoy</title>
      <link>https://dev.to/dubadub</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dubadub"/>
    <language>en</language>
    <item>
      <title>How I almost automated grocery shopping</title>
      <dc:creator>Alexey Dubovskoy</dc:creator>
      <pubDate>Tue, 01 Feb 2022 14:28:44 +0000</pubDate>
      <link>https://dev.to/dubadub/how-i-almost-automated-grocery-shopping-4p5c</link>
      <guid>https://dev.to/dubadub/how-i-almost-automated-grocery-shopping-4p5c</guid>
      <description>&lt;p&gt;With the pandemic everyone's got their own challenges. For me it became particularly hard to switch to online grocery shopping. &lt;/p&gt;

&lt;p&gt;In my typical order I'd buy groceries for 7-10 days and it will contain 60-80 items in a cart. When I do my shopping offline I usually don't plan much and go through all the departments and pick up stuff as I go. It's rare when I forget to buy something because it catches my eye, but more often I buy something that I don't need (well, that's how supermarkets designed to work).&lt;/p&gt;

&lt;p&gt;Online is a different story. I can't reproduce the same behaviour and go through the whole catalog. So I needed to plan my meals. I'd written down ingredients for my recipes on sticky notes and combined them to make an order.&lt;/p&gt;

&lt;p&gt;This was really tedious. After a few orders I noticed that it was kind of repetitive. Although my wife will tell you that I just was lazy and didn't want to do boring stuff, the developer in me said that it's time to automate this and never solve the same problem again. &lt;/p&gt;

&lt;p&gt;That's how &lt;a href="https://cooklang.org" rel="noopener noreferrer"&gt;Cooklang&lt;/a&gt; was born.&lt;/p&gt;

&lt;h2&gt;
  
  
  About Cooklang
&lt;/h2&gt;

&lt;p&gt;I though what if I store my recipes in Markdown-like text files and tag ingredients with &lt;code&gt;@&lt;/code&gt; symbol? Like that:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bk1w72fuhmd8su6r666.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3bk1w72fuhmd8su6r666.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;That will make recipe files human and machine readable. &lt;/p&gt;

&lt;p&gt;Given these recipe files computers can create a shopping list and actually do much more: calculate nutrition values, costs or whatever given that information for ingredients provided.&lt;/p&gt;

&lt;p&gt;And as it's stays human readable, that means I can be agile and store my recipes in git and perfect them over time (like code refactoring). &lt;/p&gt;

&lt;p&gt;Also because it's just a simple text format I avoid "vendor lock-in" problem and still can use my recipes the same way when I retire. My recipes are mine, forever.&lt;/p&gt;

&lt;h2&gt;
  
  
  About tools
&lt;/h2&gt;

&lt;p&gt;Having only a language specification isn't really helpful. Yes, I can store my recipes on GitHub and own them, but that's it. &lt;/p&gt;

&lt;p&gt;I imagined that it would be nice to have many small applications which can understand the language and do their own small thing very well: calculate calories, shopping, costs, smart meal planning, etc. I was really excited.&lt;/p&gt;

&lt;p&gt;I read a wonderful book &lt;a href="http://craftinginterpreters.com" rel="noopener noreferrer"&gt;Crafting Interpreters&lt;/a&gt; by Robert Nystrom and did a few experiments and I created a simple &lt;a href="https://github.com/cooklang/CookInSwift" rel="noopener noreferrer"&gt;parser&lt;/a&gt; and &lt;a href="https://github.com/cooklang/CookCLI" rel="noopener noreferrer"&gt;CLI app&lt;/a&gt;. As I want to focus here on how I automated shopping I might do another post about the parser and CLI if anyone interested, so I skip all the details.&lt;/p&gt;

&lt;p&gt;So CLI can understand Cooklang files, extract ingredients, and group them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cook shopping-list \
&amp;gt; Neapolitan\ Pizza.cook \
&amp;gt; Root\ Vegetable\ Tray\ Bake.cook
BREADS AND BAKED GOODS
    breadcrumbs                   150 g

DRIED HERBS AND SPICES
    dried oregano                 3 tbsp
    dried sage                    1 tsp
    pepper                        1 pinch
    salt                          25 g, 2 pinches

FRUIT AND VEG
    beetroots                     300 g
    carrots                       300 g
    celeriac                      300 g
    fresh basil                   18 leaves
    garlic                        3 gloves
    lemon                         1 item
    onion                         1 large
    red onion                     2 items
    thyme                         2 springs

MEAT AND SEAFOOD
    parma ham                     3 packs

MILK AND DAIRY
    butter                        15 g
    egg                           1 item
    mozzarella                    3 packs

OILS AND DRESSINGS
    Dijon mustard                 1 tsp
    Marmite                       1 tsp
    cider                         150 ml
    olive oil                     3 tbsp

OTHER (add new items into aisle.conf)
    tipo zero flour               820 g

PACKAGED GOODS, PASTA AND SAUCES
    vegetable stock               150 ml
    water                         530 ml

TINNED GOODS AND BAKING
    cannellini beans              400 g
    chopped tomato                3 cans
    fresh yeast                   1.6 g
    redcurrant jelly              1 tsp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I also can set output format to &lt;code&gt;json&lt;/code&gt; or &lt;code&gt;yaml&lt;/code&gt; and feed this into other programs. Or just use good old plain text output manipulation and pipes in shell. It has a few more features like a web-server to explore the recipes with cooking mode and make shopping list in the browser.&lt;/p&gt;

&lt;p&gt;I migrated a bunch of recipes from scattered sources into Cooklang format and stored them on GitHub repository &lt;a href="https://github.com/dubadub/cookbook" rel="noopener noreferrer"&gt;https://github.com/dubadub/cookbook&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  My grocery shopping approach
&lt;/h2&gt;

&lt;p&gt;Unfortunately, I haven't got far after that and fully automated shopping yet. I still need to do some manual steps because my shop doesn't provide any API access (surprise!).&lt;/p&gt;

&lt;p&gt;That's how my process looks now:&lt;/p&gt;

&lt;p&gt;1/ I generate a list of all ingredients. I added directories with symlinks to recipes which represent a meal plan. So it's easy to generate a list of ingredients for the whole directory like that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ cook shopping-list --only-ingredients ./Plan\ I
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2/ I remove from the list whatever I have at home.&lt;/p&gt;

&lt;p&gt;3/ I paste all the ingredients to a multi search input on the shop's web-site:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr3r1gxfw1218il7hhcv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpr3r1gxfw1218il7hhcv.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;4/ I manually go through each item and add to a cart 😓.&lt;/p&gt;

&lt;p&gt;5/ Done!&lt;/p&gt;

&lt;p&gt;It has a manual step, but still:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;much faster than before;&lt;/li&gt;
&lt;li&gt;has less cognitive load to my brain;&lt;/li&gt;
&lt;li&gt;more precise. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I'm really happy with this precision part. I noticed that I now cover all my needs but not over consume. Eco-sufficiency in some way.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next
&lt;/h2&gt;

&lt;p&gt;I solved only 80% of my problem and I want to do more. I'm thinking to create a mapping between ingredients from my recipes and links to them at my shop's web-site. That will allow me to use &lt;code&gt;curl&lt;/code&gt; or Selenium to complete the problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Links
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://cooklang.org" rel="noopener noreferrer"&gt;Cooklang web-site&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cooklang/CookInSwift" rel="noopener noreferrer"&gt;Parser&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/cooklang/CookCLI" rel="noopener noreferrer"&gt;CLI&lt;/a&gt;&lt;br&gt;
&lt;a href="https://github.com/dubadub/cookbook" rel="noopener noreferrer"&gt;My recipes&lt;/a&gt;&lt;/p&gt;

</description>
      <category>programming</category>
      <category>cooking</category>
      <category>opensource</category>
      <category>showdev</category>
    </item>
  </channel>
</rss>
