```json
{
  "sym_variables": [
    ("x0", "ravioli"),
    ("x1", "knishes"),
    ("x2", "chicken drumsticks")
  ],
  "objective_function": "6.2 * x0 + 1.9 * x1 + 6.3 * x2",
  "constraints": [
    "0.37 * x0 + 0.97 * x2 >= 10",
    "0.37 * x0 + 0.83 * x1 >= 3",
    "0.37 * x0 + 0.83 * x1 + 0.97 * x2 >= 3",
    "1.18 * x1 + 0.14 * x2 >= 14",
    "0.39 * x0 + 0.14 * x2 >= 9",
    "0.39 * x0 + 1.18 * x1 >= 8",
    "0.39 * x0 + 1.18 * x1 + 0.14 * x2 >= 9",
    "-2 * x0 + 6 * x1 >= 0",
    "0.37 * x0 + 0.83 * x1 <= 21",
    "0.39 * x0 + 0.14 * x2 <= 51",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    ravioli = m.addVar(vtype=gp.GRB.CONTINUOUS, name="ravioli")
    knishes = m.addVar(vtype=gp.GRB.CONTINUOUS, name="knishes")
    chicken_drumsticks = m.addVar(vtype=gp.GRB.CONTINUOUS, name="chicken_drumsticks")

    # Set objective function
    m.setObjective(6.2 * ravioli + 1.9 * knishes + 6.3 * chicken_drumsticks, gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(0.37 * ravioli + 0.97 * chicken_drumsticks >= 10, "tastiness_ravioli_chicken")
    m.addConstr(0.37 * ravioli + 0.83 * knishes >= 3, "tastiness_ravioli_knishes")
    m.addConstr(0.37 * ravioli + 0.83 * knishes + 0.97 * chicken_drumsticks >= 3, "tastiness_all")
    m.addConstr(1.18 * knishes + 0.14 * chicken_drumsticks >= 14, "protein_knishes_chicken")
    m.addConstr(0.39 * ravioli + 0.14 * chicken_drumsticks >= 9, "protein_ravioli_chicken")
    m.addConstr(0.39 * ravioli + 1.18 * knishes >= 8, "protein_ravioli_knishes")
    m.addConstr(0.39 * ravioli + 1.18 * knishes + 0.14 * chicken_drumsticks >= 9, "protein_all")
    m.addConstr(-2 * ravioli + 6 * knishes >= 0, "ravioli_knishes_relation")
    m.addConstr(0.37 * ravioli + 0.83 * knishes <= 21, "tastiness_ravioli_knishes_max")
    m.addConstr(0.39 * ravioli + 0.14 * chicken_drumsticks <= 51, "protein_ravioli_chicken_max")


    # Optimize model
    m.optimize()

    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('Optimization problem is infeasible.')
    else:
        print('Optimization ended with status %d' % m.status)


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

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