```json
{
  "sym_variables": [
    ("x0", "hot dogs"),
    ("x1", "blueberry pies"),
    ("x2", "milkshakes"),
    ("x3", "bowls of cereal")
  ],
  "objective_function": "8*x0 + 7*x1 + 8*x2 + 3*x3",
  "constraints": [
    "17*x1 + 23*x2 >= 73",
    "22*x0 + 23*x2 >= 107",
    "22*x0 + 17*x1 + 23*x2 + 11*x3 >= 107",
    "4*x0 + 14*x2 >= 45",
    "14*x2 + 13*x3 >= 28",
    "19*x1 + 14*x2 >= 27",
    "4*x0 + 19*x1 >= 67",
    "4*x0 + 13*x3 >= 43",
    "4*x0 + 19*x1 + 14*x2 + 13*x3 >= 43",
    "-8*x0 + 8*x3 >= 0",
    "x1 - 10*x2 >= 0",
    "22*x0 + 11*x3 <= 143",
    "22*x0 + 23*x2 <= 247",
    "22*x0 + 17*x1 + 11*x3 <= 222",
    "22*x0 + 23*x2 + 11*x3 <= 138",
    "22*x0 + 17*x1 + 23*x2 <= 166",
    "14*x2 + 13*x3 <= 187",
    "22*x0 + 4*x0 <= 435",
    "19*x1 + 14*x2 + 13*x3 <= 315"

  ]
}
```

```python
import gurobipy as gp
from gurobipy import GRB

# Create a new model
m = gp.Model("food_optimization")

# Create variables
hot_dogs = m.addVar(vtype=GRB.INTEGER, name="hot_dogs")
blueberry_pies = m.addVar(vtype=GRB.CONTINUOUS, name="blueberry_pies")
milkshakes = m.addVar(vtype=GRB.CONTINUOUS, name="milkshakes")
bowls_of_cereal = m.addVar(vtype=GRB.INTEGER, name="bowls_of_cereal")

# Set objective function
m.setObjective(8*hot_dogs + 7*blueberry_pies + 8*milkshakes + 3*bowls_of_cereal, GRB.MINIMIZE)

# Add constraints
m.addConstr(17*blueberry_pies + 23*milkshakes >= 73)
m.addConstr(22*hot_dogs + 23*milkshakes >= 107)
m.addConstr(22*hot_dogs + 17*blueberry_pies + 23*milkshakes + 11*bowls_of_cereal >= 107)
m.addConstr(4*hot_dogs + 14*milkshakes >= 45)
m.addConstr(14*milkshakes + 13*bowls_of_cereal >= 28)
m.addConstr(19*blueberry_pies + 14*milkshakes >= 27)
m.addConstr(4*hot_dogs + 19*blueberry_pies >= 67)
m.addConstr(4*hot_dogs + 13*bowls_of_cereal >= 43)
m.addConstr(4*hot_dogs + 19*blueberry_pies + 14*milkshakes + 13*bowls_of_cereal >= 43)
m.addConstr(-8*hot_dogs + 8*bowls_of_cereal >= 0)
m.addConstr(blueberry_pies - 10*milkshakes >= 0)
m.addConstr(22*hot_dogs + 11*bowls_of_cereal <= 143)
m.addConstr(22*hot_dogs + 23*milkshakes <= 247)
m.addConstr(22*hot_dogs + 17*blueberry_pies + 11*bowls_of_cereal <= 222)
m.addConstr(22*hot_dogs + 23*milkshakes + 11*bowls_of_cereal <= 138)
m.addConstr(22*hot_dogs + 17*blueberry_pies + 23*milkshakes <= 166)
m.addConstr(14*milkshakes + 13*bowls_of_cereal <= 187)


m.addConstr(22*hot_dogs + 4*hot_dogs <= 435) #protein from hotdogs
m.addConstr(19*blueberry_pies + 14*milkshakes + 13*bowls_of_cereal <= 315) # calcium


# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print('Obj: %g' % m.objVal)
    for v in m.getVars():
        print('%s %g' % (v.varName, v.x))
elif m.status == GRB.INFEASIBLE:
    print('Model is infeasible')
else:
    print('Optimization ended with status %d' % m.status)

```