```json
{
  "sym_variables": [
    ("x0", "grams of fiber"),
    ("x1", "milligrams of vitamin B9"),
    ("x2", "grams of protein")
  ],
  "objective_function": "9.54 * x0 + 4.75 * x1 + 3.24 * x2",
  "constraints": [
    "1.04 * x0 + 0.49 * x1 >= 117",
    "1.04 * x0 + 0.26 * x2 >= 109",
    "1.04 * x0 + 0.49 * x1 + 0.26 * x2 >= 109",
    "2.48 * x0 + 0.8 * x2 >= 93",
    "2.48 * x0 + 0.03 * x1 >= 46",
    "2.48 * x0 + 0.03 * x1 + 0.8 * x2 >= 46",
    "0.44 * x0 + 2.45 * x2 >= 85",
    "0.44 * x0 + 0.64 * x1 >= 34",
    "0.44 * x0 + 0.64 * x1 + 2.45 * x2 >= 34",
    "6 * x1 - 8 * x2 >= 0",
    "2 * x0 - 3 * x1 >= 0",
    "0.49 * x1 + 0.26 * x2 <= 148",
    "0.44 * x0 + 0.64 * x1 <= 156",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0",
    "x1 == int",  
    "x2 == int" 
  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    fiber = m.addVar(vtype=gp.GRB.CONTINUOUS, name="fiber")
    vitamin_b9 = m.addVar(vtype=gp.GRB.INTEGER, name="vitamin_b9")
    protein = m.addVar(vtype=gp.GRB.INTEGER, name="protein")


    # Set objective function
    m.setObjective(9.54 * fiber + 4.75 * vitamin_b9 + 3.24 * protein, gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(1.04 * fiber + 0.49 * vitamin_b9 >= 117, "c0")
    m.addConstr(1.04 * fiber + 0.26 * protein >= 109, "c1")
    m.addConstr(1.04 * fiber + 0.49 * vitamin_b9 + 0.26 * protein >= 109, "c2")
    m.addConstr(2.48 * fiber + 0.8 * protein >= 93, "c3")
    m.addConstr(2.48 * fiber + 0.03 * vitamin_b9 >= 46, "c4")
    m.addConstr(2.48 * fiber + 0.03 * vitamin_b9 + 0.8 * protein >= 46, "c5")
    m.addConstr(0.44 * fiber + 2.45 * protein >= 85, "c6")
    m.addConstr(0.44 * fiber + 0.64 * vitamin_b9 >= 34, "c7")
    m.addConstr(0.44 * fiber + 0.64 * vitamin_b9 + 2.45 * protein >= 34, "c8")
    m.addConstr(6 * vitamin_b9 - 8 * protein >= 0, "c9")
    m.addConstr(2 * fiber - 3 * vitamin_b9 >= 0, "c10")
    m.addConstr(0.49 * vitamin_b9 + 0.26 * protein <= 148, "c11")
    m.addConstr(0.44 * fiber + 0.64 * vitamin_b9 <= 156, "c12")


    # Optimize model
    m.optimize()

    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('Fiber: %g' % fiber.x)
        print('Vitamin B9: %g' % vitamin_b9.x)
        print('Protein: %g' % protein.x)
    elif m.status == gp.GRB.INFEASIBLE:
        print('The model is infeasible.')
    else:
        print('Optimization ended with status %d' % m.status)


except gp.GurobiError as e:
    print('Error code ' + str(e.errno) + ': ' + str(e))

except AttributeError:
    print('Encountered an attribute error')
```