# Fobot

FoBot the Robot is a program that can help you decide what to eat to meet your nutritional goals. You enter the food you have into the input spreadsheet, you enter your calorie and macro goals, and you decide on which goals you would like most to satisfy. It will then tell you how to meet those goals with the food you specify. FoBot is completely apathetic as to whether the food you input is “healthy” or not, and can even tell you how to meet your goals using only junk food. If you’d like, you can even use it as a way to healthily maximize your junk food consumption.

For now, I’m distributing FoBot as a Windows binary.

### Basic usage

FoBot doesn’t have a user interface per se; the main way you interact with it is through an input spreadsheet, which you select when you run FoBot.exe. An example file, FoBot_example.xlsx, is included in the download. Open it in your preferred spreadsheet program and you’ll see something like this:

The top section is all about the food items you want to include in your virtual pantry. The Servings column is where you enter the number of servings you’ve already eaten. In this example, I’ve eaten 3 servings of Greek yogurt, 1 serving of Kashi, etc. The items that you would like the program to use have their servings marked with an x; the program solves for x. There are, of course, columns for the data that can be entered: Calories, Fat, Fiber, Protein, and Carbs. There is also an optional Serving Size column that you can use for convenience. There are also some Optional Parameters, but ignore these for now.

The middle section contains the totals and goals. The row that says Total Consumed is just a spreadsheet sum of the calories and macros you’ve already eaten. In this example, I’ve eaten 1530 calories, 33 g of fat, 23 g of fiber, etc. Goal min and Goal max are where you set the goal ranges you are trying to reach. In this example, I want to eat between 1980 and 2020 calories while having at least 52.5 g of fat, 35 g of fiber, and 150 g of protein. Remaining isn’t used by the program but is included for convenience; it tells you how much more you have to eat to meet your goals.

The bottom section is all about program configuration. The Constraint priority section is where you tell the program what goals are most important to you. Here, I set the protein minimum and fiber minimum to be the most important, followed by the calorie range, followed by the fat minimum. (The topmost row is the highest priority, and constraints at the same level are given the same priority.) The valid options here are Calorie min/max, Carb min/max, Fat min/max, Fiber min/max, and Protein min/max. Default parameters correspond to the optional parameters mentioned above.

### Example output

Leave FoBot_example.xlsx unchanged and select it when you run FoBot.exe. If it is successful, an HTML file will be generated and opened in your default browser. It should look something like this:

FoBot used the items marked with an x to generate a meal plan for you that met all of your goals; in this case it decided on 1 serving of turkey burgers, 1 serving of sausage, 1.11 servings of cheese, and 1 serving of FiberOne cereal. For items whose serving size is specified, it will also display the corresponding physical quantity.

### Optional parameters

Once you have a feeling for how the program operates, you can start putting constraints on the serving sizes through the use of the optional parameters. Min and Max are the minimum and maximum number of servings you would like to have (if any). Inc is used when you want the servings to be a whole number of some increment. For example, you wouldn’t want to eat a partial Turkey Burger, so Inc is set to 1. Likewise, a serving size for the Sausages are 3 links, and so Inc is set to 1/3.

Tier is used to designate some foods as backup food. The basic idea is that you may not want to eat certain items unless you have to in order to meet your goals. The program will run multiple times, once at each tier, and will exclude any items whose tier value is larger than the current level. Finally, there’s Cost. It is often the case that you can meet your goals in many ways, and cost helps you pick one way in particular. When the program is able to meet all of the supplied constraints, it will minimize this net cost; items with a high cost will not be used unless necessary, and things with a low or negative cost will be preferred.

All of the optional parameters can be left blank, it which case they will default to the value in the Default parameters row.

### Tips

• If the program is consistently unable to hit all of your goals, the food you have is unable to meet them. For this reason it is helpful to keep a couple of foods that are high in each macro, e.g. chicken for protein or fiber cereal for fiber. These types of food are the reason I introduced tiers.
• Insert or delete new rows by right-clicking the row number and clicking “Insert” or “Delete.”
• If you go over or under your goals for one day, you can make up for them the next day by copying the Remaining line into a fake food item with -1 servings on the following day.
• Although you can set the goal minimum to be equal to the goal maximum for a macro, it is not recommended. Making the goal so precise causes FoBot to prefer food without an Increment value.
• Cost can be pretty much whatever you want it to be. If you’re on a budget it could be an actual cost, in which case you’d enter the price per serving and FoBot would tell you the cheapest way to meet your goals. You could also set the cost based purely on how much you like each item, assigning items you like a large negative number and items you don’t like a less negative number.

### Technical details

Essentially, FoBot is just a wrapper for a series of mixed-integer quadratic programming problems. It started off as a MATLAB script, and I converted to Python to distribute it. When all of the constraints are met, FoBot just solves a mixed integer linear program:

$$\textrm{min} f^T x \textrm{ such that } Ax\leq b$$

where x is the state vector, f is the cost vector, and A is the constraint matrix. When some of the constraints can’t be met, FoBot allows the least important constraints to be unmet and instead solves a quadratic program on the most important unmet constraints:

$$\textrm{min} \left\| A_u x – b_u \right\|^2 \textrm{ such that } A_m x \leq b$$

where Au is the matrix of unmet constraints and Am is the matrix of met constraints.