```json
{
  "sym_variables": [
    ("x0", "milkshakes"),
    ("x1", "cheeseburgers"),
    ("x2", "bananas")
  ],
  "objective_function": "8*x0 + 4*x1 + 4*x2",
  "constraints": [
    "1*x0 + 3*x1 + 1*x2 >= 16",
    "11*x0 + 5*x2 <= 31",
    "11*x0 + 1*x1 <= 42",
    "1*x1 + 5*x2 <= 27",
    "11*x0 + 1*x1 + 5*x2 <= 27",
    "1*x0 + 3*x1 <= 69",
    "1*x0 + 3*x1 + 1*x2 <= 69",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

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

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

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


# Set objective function
m.setObjective(8 * milkshakes + 4 * cheeseburgers + 4 * bananas, GRB.MAXIMIZE)

# Add constraints
m.addConstr(1 * milkshakes + 3 * cheeseburgers + 1 * bananas >= 16, "min_cost")
m.addConstr(11 * milkshakes + 5 * bananas <= 31, "fiber_milkshakes_bananas")
m.addConstr(11 * milkshakes + 1 * cheeseburgers <= 42, "fiber_milkshakes_cheeseburgers")
m.addConstr(1 * cheeseburgers + 5 * bananas <= 27, "fiber_cheeseburgers_bananas")
m.addConstr(11 * milkshakes + 1 * cheeseburgers + 5 * bananas <= 27, "fiber_total")
m.addConstr(1 * milkshakes + 3 * cheeseburgers <= 69, "cost_milkshakes_cheeseburgers")
m.addConstr(1 * milkshakes + 3 * cheeseburgers + 1 * bananas <= 69, "cost_total")



# Optimize model
m.optimize()

# Check if a solution was found
if m.status == GRB.OPTIMAL:
    print('Optimal objective value:', m.objVal)
    print('Solution:')
    print(f'  milkshakes: {milkshakes.x}')
    print(f'  cheeseburgers: {cheeseburgers.x}')
    print(f'  bananas: {bananas.x}')
elif m.status == GRB.INFEASIBLE:
    print('The model is infeasible.')
else:
    print(f'Optimization ended with status {m.status}')

```