I’ve written about this before, but for those who haven’t seen those posts, I’ve had nothing short of a barrage of issues surrounding food and gastrointenstinal issues since I started my Ph.D., which has drastically – I’m not joking, quite drastically – altered my life in quite a few ways.
The major problems started around the time I turned 35 – shortly after I started my Ph.D. program – with what seemed to be a intolerance to lactose and ended up actually being celiac disease. It took me quite a while to realize what was actually happening after seeing a number of doctors, being unable to go to work when I was interning at Microsoft Research that summer, and resulting in some horrific levels of depression – all from eating food and drink, to put it simply. Further exacerbating the issue was that I was living in Belgium at the time on a strict diet of waffles in the morning, baguettes at lunch, baguettes at dinner, and lots and lots of beer for dessert – hey, I was in Belgium!
It took me a long time to get into a rhythm that worked for me. When I say a long time, I mean, it wasn’t until the start of the coronavirus quarantine (March 2020, over two years after I realized I couldn’t handle gluten) to get into the rhythm of things. I constantly took risks – eating out, where I got burned by shared fryolators, cross-contaminated work stations, etc. It wasn’t really until the quarantine – where, I worked an internship remotely – that I was able to actually afford cookware (keep in mind, I moved to Belgium and back with almost nothing – my apartment was empty at the start of the quarantine) and had the time to sit down and actually learn to cook meals. To this end, I used all of the available money I had to buy more cookware, buy food, and take cooking classes.
However, I was still sick. Still, no matter what I cooked, I was still bothered by what I was cooking. After hours of talking to people, cutting out item by item, learning about the IBS symptoms I was experiencing, and running through the low-FODMAP elimination diet – most likely culprit since many with celiac disease develop IBS – turns out, yup, I couldn’t have onion, garlic, or any alliums. I cut them all out and I’ve been free of garlic and onion – a very sad, sad life, in many ways – since at least May of 2020.
Until about late November, I thought I was feeling pretty good.
I was feeling significanly better than I had been previously, but I knew something was still off. Something was still bothering me regardless of how careful I was. In fact, the coronovirus quarantine had been a blessing, as now I know that every time I feel sick, it’s because of something I did: it’s all my fault. Not to be disgusting, but anyone who’s dealing with these issues knows that it’s an alternating cycle of a week of constipation and then two to three days of horrific diarrhea combined with massive weight flucuations: I’ve recently been tracking these flucuations with a IoT scale and see variations from the days where I fuck up by eating something I shouldn’t where my weight varies between 10 pounds where I feel so shitty that just the thought of putting on pants, that I know will not fit properly if at all that day, makes me seek cover on the couch in sweatpants and hide under a blanket watching Law and Order reruns. In many ways, the coronavirus quarantine has been a blessing for this as well: thankfully, we all are living our best lives behind computer screens that disguise our sweatpants addictions.
Recently, I decided I needed to get blood tested for food sensitivites because I knew something that I was eating was bothering me. I had suspicions: mornings that followed the days where I ate peanut butter were very bad; raw almonds made me 16-year-old-just-smoked-a-bowl nervous, mustard occasionally gave me the i-m-about-to-present-at-a-major-systems-conference level anxiety, and my latest quarantine comfort food – early evening cashewmilk ice cream during the Celtics basketball game – gave me levels of heartburn and indigestion that kept me up all night resulting in not being able to work at all the following morning.
My test results showed lots of new-to-me food sensitivities that I wasn’t aware of:
This was last Thursday. I figured, well, OK. I’ll figure something out this week on how to address this. Adjusting a diet with a fridge full of food isn’t cheap and I’m not one to let food go to waste.
However, as I finished lunch today while trying to figure out what the hell I’m going to do about the diet, I sat back down at the computer and felt sluggish, tired, and barely able to focus. I thought about what I had eaten for lunch: gluten-free bread made with egg, vegan mayo, bell peppers, an apple, and potato chips.
No wonder I felt like shit, and now I’m gonna have to lay down for a few hours, work late, and probably wake up late.
I’ve tried really hard to not let this situtation bother me the past few years: I say to myself, well, this is the hand that was dealt to you, play it, but I won’t deny that it’s both depressing and difficult: it’s really draining to have to examine, check, and think through every item you eat when it comes to breakfast, lunch, and dinner. It’s even harder when the list is so long that you can’t even keep it in your head: it’s just too, too much stuff that I have to print out a list of things to check for. I can’t even imagine a traditional academic life where I have to travel to conferences: in fact, the last time I had to travel, the ACM told me they could handle a gluten-free person OR a dairy-free person, but not both. Based on this, there’s not expectation that they would even comprehend someone with the level of shit I have to avoid.
The way I saw it previously, is pretty easy to comprehend from an avoidance strategy:
However, that’s obviously not the whole story for me now: IBS requires I avoid gluten and onion, and since I don’t feel well still, I still need to go further. Therefore, I need to do another eliminiation diet and the list of foods is 35 items long; obviously I’ll start the elimination diet with the ones at the top of the list. Sounds easy? It’s not. I’m sure many of you just pickup foods without even thinking: yeah, I don’t do that. Honestly, food shopping and preparation for the week and checking items is more stressful than programming for me now – in jest, I’d say implementing Paxos is easier for me at this point.
But, the question is – what the hell do I actually eat?
At the start of the coronavirus quarantine, when I was trying to learn to cook things I could eat, I spent a lot of time buying and reading cookbooks. I picked cuisines that minimized on dairy (due to availability or regional restrictions, etc.) and gluten (for similar reasons.) I bought vegan cookbooks – but had to skip the soy and gluten, I bought vegetarian cookbooks and adjusted accordingly. I bought gluten-free baking cookbooks. I adapted as many recipes I could using alternate ingredients to cook them soy-free, garlic-free, onion-free, and gluten-free. This seemed to work well for me, but I’d never have anyone over because I’m pretty sure that the food was tasteless – at this point food is merely something that I cook because I have to eat to survive.
(As someone who started a Ph.D. in Europe with the goal of teaching in Paris for the food, this is a life-changing moment.)
This doesn’t work anymore. There’s no way to adapt recipes that require eggs as a core ingredient at this point – there’s no cookbook that fits this weird as diet I need to adjust to.
I made a joke on Twitter earlier today that I would need a Prolog program to come up with something that I could actually eat and after a discussion with a friend, I thought, surely this is a constraint program and really, for a recipe to work for me, it just had to be satisfiable, right?
I spent a bit of time trying to figure out how to encode this into Z3, but knowing that my last attempt to do any serious string work with Z3 failed horrifically, I thought, well, surely I could write a little bit of Python to solve the problme.
So, let’s look at a good first attempt – written at 11 PM in a moment of desperation, maybe?
First, we encode the foods we can’t have. I broke mine down into a few different categories. For example, I have a category of foods that I know will trigger an autoimmune response:
food_autoimmune_response = {
"wheat": {},
"rye": {},
"all-purpose flour": { "subs": ["all-purpose gluten free flour" ] },
"barley": {},
"gluten": {},
"bread": { "subs": [ "dairy-free, egg-free, soy-free, gluten-free bread" ] },
"sourdough": {}
}
I use a map for each food and then a key to indiciate a list of possible substitutions. For example, I know that I can use an all-purpose gluten-free flour to substitute for a regular all-purpose flour; similiarly, I know that I can use a dairy-free, egg-free, soy-free, gluten-free bread to replace a bread in a recipe that calls for sandwich or sourdough bread.
I do the same for other foods, for example, my known food intolerances:
food_intolerances = {
"parmesan": {},
"yogurt": {},
"butter": {},
"dairy": {},
"cheese": {},
"sour cream": {},
"milk": { "subs": [ "oat milk" ] }
"cottage cheese": {}
}
Here, I haven’t filled out the substitutions yet. Mainly, because my normal substitutions for parmesan and sour cream both contain soy, which I just found out I have to cut out with my new elimination diet.
Next, I use a list to accumlate the items that match in the recipe. I put this in a function, cause I have several different lists: autoimmune responses, intolerances, class 3 sensitivites, class 2, etc.
def check_item(item, recipe, list):
print("=> " + item)
matcher = re.compile(r'\b%s\b' % item, re.IGNORECASE)
if matcher.search(recipe):
list.append(item)
This way, I can run it for all of the lists dynamically. I use word boundaries on the regexp to avoid matching ‘Fryer’ when looking for recipes with ‘rye’ as an ingredient.
I run this for each list, like so:
print("Checking items that trigger an autoimmune response: ")
print("")
for item in food_autoimmune_response:
check_item(item, recipe, food_autoimmune_response_found)
print("")
Once that’s done, I iterate each list looking for items for which there are no substitutes:
def print_results(list, found_list):
for item in found_list:
if 'subs' in list[item]:
print("Found: " + item + "; however, possible substituions: " + str(list[item]['subs']))
else:
print("Found: " + item + "; no subs.")
fatal = 1
print("Autoimmune response triggering ingredients:")
print("")
print_results(food_autoimmune_response, food_autoimmune_response_found)
print("")
If I can’t find a substitute for every possible ingredient – gluten-free alternatives for gluten-containing items, other acidic items for citrus I can’t consume, dairy alternatives, I fail the entire thing by setting the fatal value to 1. Then, at the end I print out that this recipe isn’t good.
To get the recipes, I take them in the command line and use a HTTP library to get them. For example, if I wanted to have my favorite meal when I lived in Europe, the croque monsieur:
$ clear; python3 food.py https://www.foodnetwork.com/recipes/ina-garten/croque-monsieur-recipe-1916523e
My script would tell me:
================ Results ==================
Autoimmune response triggering ingredients:
Found: bread; however, possible substituions: ['dairy-free, egg-free, soy-free, gluten-free bread']
Intolerances:
Found: parmesan; no subs.
Found: butter; no subs.
Found: cheese; no subs.
Found: milk; however, possible substituions: ['oat milk']
Now, I could find substitues for parmesan, butter, cheese, and milk, but at this point I haven’t found good alterantives for milk (all alternatives use cashew, soy, coconut, or almond, which I can’t have – with the exception of oat milk, which I haven’t cooked with); butter (vegany buttery sticks might work, but haven’t verified soy content), cheese (Daiya might work, have to recheck with new sensitivies) nor parmesan (all known replacements use soy or almond.)
Now, this seems great, but it’s not all perfect. I found a number of problems with this after I made it:
We’ll just have to see what the future brings.
Thanks for reading.