```json
{
  "sym_variables": [
    ("x0", "bananas"),
    ("x1", "milkshakes")
  ],
  "objective_function": "9.92 * x0 * x1 + 7.8 * x1**2 + 3.23 * x0 + 6.31 * x1",
  "constraints": [
    "x0**2 + x1**2 >= 15",
    "7 * x0**2 - 8 * x1**2 >= 0",
    "x0 + x1 <= 36",
    "x0 + 6*x1 <= 47"
  ]
}
```

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

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

    # Create variables
    bananas = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="bananas")
    milkshakes = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="milkshakes")


    # Set objective function
    m.setObjective(9.92 * bananas * milkshakes + 7.8 * milkshakes**2 + 3.23 * bananas + 6.31 * milkshakes, GRB.MAXIMIZE)

    # Add constraints
    m.addConstr(bananas**2 + milkshakes**2 >= 15, "c0")
    m.addConstr(7 * bananas**2 - 8 * milkshakes**2 >= 0, "c1")
    m.addConstr(bananas + milkshakes <= 36, "c2")
    m.addConstr(bananas + 6 * milkshakes <= 47, "c3")


    # Optimize model
    m.optimize()

    if m.status == GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('bananas:', bananas.x)
        print('milkshakes:', milkshakes.x)
    elif m.status == GRB.INFEASIBLE:
        print('The problem 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')

```