```json
{
  "sym_variables": [
    ("x0", "milkshakes"),
    ("x1", "oranges"),
    ("x2", "slices of pizza"),
    ("x3", "chicken drumsticks")
  ],
  "objective_function": "6.35 * x0 + 7.44 * x1 + 2.49 * x2 + 7.43 * x3",
  "constraints": [
    "4 * x0 + 5 * x2 >= 8",
    "1 * x1 + 5 * x2 >= 10",
    "5 * x2 + 5 * x3 >= 20",
    "4 * x0 + 5 * x2 + 5 * x3 >= 14",
    "1 * x1 + 5 * x3 >= 15",
    "2 * x0 + 2 * x2 >= 6",
    "2 * x2 + 5 * x3 >= 5",
    "1 * x1 + 2 * x2 >= 8",
    "2 * x0 + 1 * x1 >= 12",
    "1 * x1 + 5 * x3 <= 52",
    "1 * x1 + 5 * x2 <= 73",
    "4 * x0 + 5 * x2 <= 78",
    "4 * x0 + 5 * x2 + 5 * x3 <= 54",
    "4 * x0 + 1 * x1 + 5 * x2 + 5 * x3 <= 54",
    "3 * x2 + 4 * x3 <= 79",
    "5 * x1 + 3 * x2 <= 61",
    "3 * x0 + 4 * x3 <= 78",
    "3 * x0 + 3 * x2 <= 38",
    "3 * x0 + 5 * x1 <= 61",
    "3 * x0 + 5 * x1 + 3 * x2 + 4 * x3 <= 61",
    "2 * x0 + 2 * x2 <= 27",
    "2 * x0 + 1 * x1 <= 66",
    "2 * x2 + 5 * x3 <= 37",
    "1 * x1 + 2 * x2 <= 59",
    "1 * x1 + 5 * x3 <= 62",
    "2 * x0 + 1 * x1 + 5 * x3 <= 49",
    "2 * x0 + 2 * x2 + 5 * x3 <= 40",
    "2 * x0 + 1 * x1 + 2 * x2 + 5 * x3 <= 40",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0",
    "x3 >= 0"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
milkshakes = m.addVar(lb=0, name="milkshakes")
oranges = m.addVar(lb=0, name="oranges")
pizza_slices = m.addVar(lb=0, name="pizza_slices")
chicken_drumsticks = m.addVar(lb=0, name="chicken_drumsticks")


# Set objective function
m.setObjective(6.35 * milkshakes + 7.44 * oranges + 2.49 * pizza_slices + 7.43 * chicken_drumsticks, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(4 * milkshakes + 5 * pizza_slices >= 8)
m.addConstr(oranges + 5 * pizza_slices >= 10)
m.addConstr(5 * pizza_slices + 5 * chicken_drumsticks >= 20)
m.addConstr(4 * milkshakes + 5 * pizza_slices + 5 * chicken_drumsticks >= 14)
m.addConstr(oranges + 5 * chicken_drumsticks >= 15)
m.addConstr(2 * milkshakes + 2 * pizza_slices >= 6)
m.addConstr(2 * pizza_slices + 5 * chicken_drumsticks >= 5)
m.addConstr(oranges + 2 * pizza_slices >= 8)
m.addConstr(2 * milkshakes + oranges >= 12)
m.addConstr(oranges + 5 * chicken_drumsticks <= 52)
m.addConstr(oranges + 5 * pizza_slices <= 73)
m.addConstr(4 * milkshakes + 5 * pizza_slices <= 78)
m.addConstr(4 * milkshakes + 5 * pizza_slices + 5 * chicken_drumsticks <= 54)
m.addConstr(4 * milkshakes + oranges + 5 * pizza_slices + 5 * chicken_drumsticks <= 54)
m.addConstr(3 * pizza_slices + 4 * chicken_drumsticks <= 79)
m.addConstr(5 * oranges + 3 * pizza_slices <= 61)
m.addConstr(3 * milkshakes + 4 * chicken_drumsticks <= 78)
m.addConstr(3 * milkshakes + 3 * pizza_slices <= 38)
m.addConstr(3 * milkshakes + 5 * oranges <= 61)
m.addConstr(3 * milkshakes + 5 * oranges + 3 * pizza_slices + 4 * chicken_drumsticks <= 61)
m.addConstr(2 * milkshakes + 2 * pizza_slices <= 27)
m.addConstr(2 * milkshakes + oranges <= 66)
m.addConstr(2 * pizza_slices + 5 * chicken_drumsticks <= 37)
m.addConstr(oranges + 2 * pizza_slices <= 59)
m.addConstr(oranges + 5 * chicken_drumsticks <= 62)
m.addConstr(2 * milkshakes + oranges + 5 * chicken_drumsticks <= 49)
m.addConstr(2 * milkshakes + 2 * pizza_slices + 5 * chicken_drumsticks <= 40)
m.addConstr(2 * milkshakes + oranges + 2 * pizza_slices + 5 * chicken_drumsticks <= 40)


# Optimize model
m.optimize()

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

```