```json
{
  "sym_variables": [
    ("x0", "hours worked by Ringo"),
    ("x1", "hours worked by Bobby"),
    ("x2", "hours worked by Dale"),
    ("x3", "hours worked by Laura")
  ],
  "objective_function": "9*x0**2 + 6*x0*x1 + 5*x0*x3 + 4*x1*x3 + 9*x2*x3 + x2 + 8*x3",
  "constraints": [
    "1.38*x0 = 1.38",
    "18.15*x0 = 18.15",
    "6.59*x1 = 6.59",
    "8.98*x1 = 8.98",
    "18.38*x2 = 18.38",
    "13.32*x2 = 13.32",
    "1.66*x3 = 1.66",
    "21.23*x3 = 21.23",
    "1.38*x0 + 1.66*x3 >= 28",
    "6.59*x1 + 1.66*x3 >= 71",
    "18.38*x2 + 1.66*x3 >= 31",
    "1.38*x0**2 + 18.38*x2**2 >= 42",
    "1.38*x0**2 + 18.38*x2**2 + 1.66*x3**2 >= 69",
    "8.98*x1 + 13.32*x2 >= 79",
    "13.32*x2 + 21.23*x3 >= 45",
    "18.15*x0 + 8.98*x1 + 21.23*x3 >= 102",
    "8.98*x1**2 + 13.32*x2**2 + 21.23*x3**2 >= 102",
    "18.15*x0 + 8.98*x1 + 21.23*x3 >= 81",
    "8.98*x1**2 + 13.32*x2**2 + 21.23*x3**2 >= 81",
    "1.38*x0 + 18.38*x2 <= 298",
    "6.59*x1**2 + 18.38*x2**2 <= 220",
    "1.38*x0 + 1.66*x3 <= 169",
    "1.38*x0**2 + 6.59*x1**2 <= 144",
    "6.59*x1 + 1.66*x3 <= 93",
    "18.38*x2 + 1.66*x3 <= 149",
    "1.38*x0 + 6.59*x1 + 18.38*x2 + 1.66*x3 <= 149",
    "18.15*x0**2 + 21.23*x3**2 <= 361",
    "13.32*x2 + 21.23*x3 <= 316",
    "18.15*x0**2 + 8.98*x1**2 <= 126",
    "18.15*x0 + 13.32*x2 + 21.23*x3 <= 435",
    "18.15*x0**2 + 8.98*x1**2 + 21.23*x3**2 <= 297",
    "18.15*x0 + 8.98*x1 + 13.32*x2 + 21.23*x3 <= 297"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
ringo = m.addVar(lb=0, name="ringo")
bobby = m.addVar(lb=0, name="bobby")
dale = m.addVar(lb=0, vtype=gp.GRB.INTEGER, name="dale")
laura = m.addVar(lb=0, vtype=gp.GRB.INTEGER, name="laura")

# Set objective function
m.setObjective(9*ringo**2 + 6*ringo*bobby + 5*ringo*laura + 4*bobby*laura + 9*dale*laura + dale + 8*laura, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(1.38*ringo == 1.38)
m.addConstr(18.15*ringo == 18.15)
m.addConstr(6.59*bobby == 6.59)
m.addConstr(8.98*bobby == 8.98)
m.addConstr(18.38*dale == 18.38)
m.addConstr(13.32*dale == 13.32)
m.addConstr(1.66*laura == 1.66)
m.addConstr(21.23*laura == 21.23)


m.addConstr(1.38*ringo + 1.66*laura >= 28)
m.addConstr(6.59*bobby + 1.66*laura >= 71)
m.addConstr(18.38*dale + 1.66*laura >= 31)
m.addConstr(1.38*ringo**2 + 18.38*dale**2 >= 42)
m.addConstr(1.38*ringo**2 + 18.38*dale**2 + 1.66*laura**2 >= 69)
m.addConstr(8.98*bobby + 13.32*dale >= 79)
m.addConstr(13.32*dale + 21.23*laura >= 45)
m.addConstr(18.15*ringo + 8.98*bobby + 21.23*laura >= 102)
m.addConstr(8.98*bobby**2 + 13.32*dale**2 + 21.23*laura**2 >= 102)
m.addConstr(18.15*ringo + 8.98*bobby + 21.23*laura >= 81)
m.addConstr(8.98*bobby**2 + 13.32*dale**2 + 21.23*laura**2 >= 81)
m.addConstr(1.38*ringo + 18.38*dale <= 298)
m.addConstr(6.59*bobby**2 + 18.38*dale**2 <= 220)
m.addConstr(1.38*ringo + 1.66*laura <= 169)
m.addConstr(1.38*ringo**2 + 6.59*bobby**2 <= 144)
m.addConstr(6.59*bobby + 1.66*laura <= 93)
m.addConstr(18.38*dale + 1.66*laura <= 149)
m.addConstr(1.38*ringo + 6.59*bobby + 18.38*dale + 1.66*laura <= 149)
m.addConstr(18.15*ringo**2 + 21.23*laura**2 <= 361)
m.addConstr(13.32*dale + 21.23*laura <= 316)
m.addConstr(18.15*ringo**2 + 8.98*bobby**2 <= 126)
m.addConstr(18.15*ringo + 13.32*dale + 21.23*laura <= 435)
m.addConstr(18.15*ringo**2 + 8.98*bobby**2 + 21.23*laura**2 <= 297)
m.addConstr(18.15*ringo + 8.98*bobby + 13.32*dale + 21.23*laura <= 297)



# Optimize model
m.optimize()

# Print results
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)

```
