```json
{
  "sym_variables": [
    ("x0", "milligrams of zinc"),
    ("x1", "milligrams of vitamin B12"),
    ("x2", "milligrams of vitamin B3"),
    ("x3", "milligrams of vitamin C")
  ],
  "objective_function": "7.5 * x0 + 5.18 * x1 + 3.52 * x2 + 8.91 * x3",
  "constraints": [
    "5 * x0 + 1 * x1 >= 36",
    "5 * x0 + 18 * x2 >= 19",
    "1 * x1 + 18 * x2 + 19 * x3 >= 29",
    "5 * x0 + 1 * x1 + 19 * x3 >= 29",
    "5 * x0 + 18 * x2 + 19 * x3 >= 29",
    "1 * x1 + 18 * x2 + 19 * x3 >= 42",
    "5 * x0 + 1 * x1 + 19 * x3 >= 42",
    "5 * x0 + 18 * x2 + 19 * x3 >= 42",
    "1 * x1 + 18 * x2 + 19 * x3 >= 32",
    "5 * x0 + 1 * x1 + 19 * x3 >= 32",
    "5 * x0 + 18 * x2 + 19 * x3 >= 32",
    "5 * x0 + 1 * x1 + 18 * x2 + 19 * x3 >= 32",
    "2 * x1 + 5 * x3 >= 69",
    "2 * x1 + 13 * x2 >= 61",
    "5 * x0 + 13 * x2 >= 64",
    "5 * x0 + 5 * x3 >= 30",
    "5 * x0 + 13 * x2 + 5 * x3 >= 77",
    "5 * x0 + 2 * x1 + 13 * x2 + 5 * x3 >= 77",
    "8 * x1 - 4 * x2 >= 0",
    "5 * x0 + 1 * x1 + 19 * x3 <= 100",
    "5 * x0 + 1 * x1 + 18 * x2 <= 194",
    "5 * x0 + 18 * x2 + 19 * x3 <= 74",
    "5 * x0 + 2 * x1 + 13 * x2 <= 279",
    "5 * x0 + 2 * x1 + 5 * x3 <= 292",
    "5 * x0 + 13 * x2 + 5 * x3 <= 166",
    "x2 == int"  
  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    zinc = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="zinc")
    b12 = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="b12")
    b3 = m.addVar(lb=0, vtype=gp.GRB.INTEGER, name="b3")
    c = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="c")

    # Set objective function
    m.setObjective(7.5 * zinc + 5.18 * b12 + 3.52 * b3 + 8.91 * c, gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(5 * zinc + 1 * b12 >= 36)
    m.addConstr(5 * zinc + 18 * b3 >= 19)
    m.addConstr(1 * b12 + 18 * b3 + 19 * c >= 29)
    m.addConstr(5 * zinc + 1 * b12 + 19 * c >= 29)
    m.addConstr(5 * zinc + 18 * b3 + 19 * c >= 29)
    m.addConstr(1 * b12 + 18 * b3 + 19 * c >= 42)
    m.addConstr(5 * zinc + 1 * b12 + 19 * c >= 42)
    m.addConstr(5 * zinc + 18 * b3 + 19 * c >= 42)
    m.addConstr(1 * b12 + 18 * b3 + 19 * c >= 32)
    m.addConstr(5 * zinc + 1 * b12 + 19 * c >= 32)
    m.addConstr(5 * zinc + 18 * b3 + 19 * c >= 32)
    m.addConstr(5 * zinc + 1 * b12 + 18 * b3 + 19 * c >= 32)
    m.addConstr(2 * b12 + 5 * c >= 69)
    m.addConstr(2 * b12 + 13 * b3 >= 61)
    m.addConstr(5 * zinc + 13 * b3 >= 64)
    m.addConstr(5 * zinc + 5 * c >= 30)
    m.addConstr(5 * zinc + 13 * b3 + 5 * c >= 77)
    m.addConstr(5 * zinc + 2 * b12 + 13 * b3 + 5 * c >= 77)
    m.addConstr(8 * b12 - 4 * b3 >= 0)
    m.addConstr(5 * zinc + 1 * b12 + 19 * c <= 100)
    m.addConstr(5 * zinc + 1 * b12 + 18 * b3 <= 194)
    m.addConstr(5 * zinc + 18 * b3 + 19 * c <= 74)
    m.addConstr(5 * zinc + 2 * b12 + 13 * b3 <= 279)
    m.addConstr(5 * zinc + 2 * b12 + 5 * c <= 292)
    m.addConstr(5 * zinc + 13 * b3 + 5 * c <= 166)


    # Optimize model
    m.optimize()

    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('zinc:', zinc.x)
        print('b12:', b12.x)
        print('b3:', b3.x)
        print('c:', c.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')
```