```json
{
  "sym_variables": [
    ("x0", "hours worked by Hank"),
    ("x1", "hours worked by Mary"),
    ("x2", "hours worked by Ringo"),
    ("x3", "hours worked by John")
  ],
  "objective_function": "8*x0**2 + 5*x0*x2 + 7*x0*x3 + 5*x1**2 + 4*x2**2 + 4*x3**2 + 3*x0 + 6*x3",
  "constraints": [
    "13*x0 + 12*x2 + 1*x3 >= 77",
    "20*x1 + 1*x3 <= 156",
    "16*x0**2 + 20*x1**2 <= 326",
    "16*x0 + 16*x2 <= 404",
    "16*x0**2 + 1*x3**2 <= 213",
    "16*x2 + 1*x3 <= 146",
    "16*x0**2 + 20*x1**2 + 1*x3**2 <= 353",
    "16*x0 + 20*x1 + 16*x2 + 1*x3 <= 353",
    "4*x1 + 12*x2 <= 314",
    "4*x1 + 1*x3 <= 119",
    "13*x0**2 + 1*x3**2 <= 97",
    "13*x0**2 + 12*x2**2 <= 218",
    "13*x0 + 4*x1 <= 301",
    "13*x0 + 4*x1 + 12*x2 + 1*x3 <= 301"
  ]
}
```

```python
import gurobipy as gp
from gurobipy import GRB

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

    # Create variables
    hank = model.addVar(lb=0, vtype=GRB.CONTINUOUS, name="hank")
    mary = model.addVar(lb=0, vtype=GRB.INTEGER, name="mary")
    ringo = model.addVar(lb=0, vtype=GRB.INTEGER, name="ringo")
    john = model.addVar(lb=0, vtype=GRB.INTEGER, name="john")

    # Set objective function
    model.setObjective(8*hank**2 + 5*hank*ringo + 7*hank*john + 5*mary**2 + 4*ringo**2 + 4*john**2 + 3*hank + 6*john, GRB.MAXIMIZE)

    # Add constraints
    model.addConstr(13*hank + 12*ringo + 1*john >= 77)
    model.addConstr(20*mary + 1*john <= 156)
    model.addConstr(16*hank**2 + 20*mary**2 <= 326)
    model.addConstr(16*hank + 16*ringo <= 404)
    model.addConstr(16*hank**2 + 1*john**2 <= 213)
    model.addConstr(16*ringo + 1*john <= 146)
    model.addConstr(16*hank**2 + 20*mary**2 + 1*john**2 <= 353)
    model.addConstr(16*hank + 20*mary + 16*ringo + 1*john <= 353)
    model.addConstr(4*mary + 12*ringo <= 314)
    model.addConstr(4*mary + 1*john <= 119)
    model.addConstr(13*hank**2 + 1*john**2 <= 97)
    model.addConstr(13*hank**2 + 12*ringo**2 <= 218)
    model.addConstr(13*hank + 4*mary <= 301)
    model.addConstr(13*hank + 4*mary + 12*ringo + 1*john <= 301)


    # Optimize model
    model.optimize()

    if model.status == GRB.OPTIMAL:
        print('Obj: %g' % model.objVal)
        print('hank:', hank.x)
        print('mary:', mary.x)
        print('ringo:', ringo.x)
        print('john:', john.x)
    elif model.status == GRB.INFEASIBLE:
        print('The model is infeasible.')
    else:
        print('Optimization ended with status %d' % model.status)


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

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