```json
{
  "sym_variables": [
    ("x0", "grams of protein"),
    ("x1", "milligrams of vitamin B12"),
    ("x2", "grams of carbohydrates")
  ],
  "objective_function": "5.44 * x0 + 7.36 * x1 + 9.87 * x2",
  "constraints": [
    "12 * x0 + 12 * x1 >= 64",
    "12 * x0 + 12 * x1 + 24 * x2 >= 64",
    "7 * x0 + 8 * x2 >= 57",
    "16 * x1 + 8 * x2 >= 57",
    "7 * x0 + 16 * x1 + 8 * x2 >= 57",
    "23 * x1 + 21 * x2 >= 27",
    "7 * x0 + 23 * x1 >= 20",
    "7 * x0 + 21 * x2 >= 14",
    "7 * x0 + 23 * x1 + 21 * x2 >= 38",
    "9 * x1 - 6 * x2 >= 0",
    "12 * x0 + 12 * x1 <= 176",
    "12 * x1 + 24 * x2 <= 256",
    "12 * x0 + 24 * x2 <= 149",
    "7 * x0 + 23 * x1 <= 75",
    "12 * x0 <= 294",
    "7 * x0 <= 248",
    "7 * x0 <= 115",
    "12 * x1 <= 294",
    "16 * x1 <= 248",
    "23 * x1 <= 115",
    "24 * x2 <= 294",
    "8 * x2 <= 248",
    "21 * x2 <= 115"


  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    protein = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="protein")
    vitamin_b12 = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="vitamin_b12")
    carbohydrates = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="carbohydrates")


    # Set objective function
    m.setObjective(5.44 * protein + 7.36 * vitamin_b12 + 9.87 * carbohydrates, gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(12 * protein + 12 * vitamin_b12 >= 64, "c0")
    m.addConstr(12 * protein + 12 * vitamin_b12 + 24 * carbohydrates >= 64, "c1")
    m.addConstr(7 * protein + 8 * carbohydrates >= 57, "c2")
    m.addConstr(16 * vitamin_b12 + 8 * carbohydrates >= 57, "c3")
    m.addConstr(7 * protein + 16 * vitamin_b12 + 8 * carbohydrates >= 57, "c4")
    m.addConstr(23 * vitamin_b12 + 21 * carbohydrates >= 27, "c5")
    m.addConstr(7 * protein + 23 * vitamin_b12 >= 20, "c6")
    m.addConstr(7 * protein + 21 * carbohydrates >= 14, "c7")
    m.addConstr(7 * protein + 23 * vitamin_b12 + 21 * carbohydrates >= 38, "c8")
    m.addConstr(9 * vitamin_b12 - 6 * carbohydrates >= 0, "c9")
    m.addConstr(12 * protein + 12 * vitamin_b12 <= 176, "c10")
    m.addConstr(12 * vitamin_b12 + 24 * carbohydrates <= 256, "c11")
    m.addConstr(12 * protein + 24 * carbohydrates <= 149, "c12")
    m.addConstr(7 * protein + 23 * vitamin_b12 <= 75, "c13")

    # Resource Constraints
    m.addConstr(12 * protein <= 294, "r0_protein")
    m.addConstr(7 * protein <= 248, "r1_protein")
    m.addConstr(7 * protein <= 115, "r2_protein")
    m.addConstr(12 * vitamin_b12 <= 294, "r0_vitamin_b12")
    m.addConstr(16 * vitamin_b12 <= 248, "r1_vitamin_b12")
    m.addConstr(23 * vitamin_b12 <= 115, "r2_vitamin_b12")
    m.addConstr(24 * carbohydrates <= 294, "r0_carbohydrates")
    m.addConstr(8 * carbohydrates <= 248, "r1_carbohydrates")
    m.addConstr(21 * carbohydrates <= 115, "r2_carbohydrates")



    # Optimize model
    m.optimize()

    # Print solution
    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('Protein: %g' % protein.x)
        print('Vitamin B12: %g' % vitamin_b12.x)
        print('Carbohydrates: %g' % carbohydrates.x)
    elif m.status == gp.GRB.INFEASIBLE:
        print('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')
```