```json
{
  "sym_variables": [
    ("x0", "protein bars"),
    ("x1", "granola bars"),
    ("x2", "black beans"),
    ("x3", "chicken breasts")
  ],
  "objective_function": "8*x0 + 4*x1 + 9*x2 + 2*x3",
  "constraints": [
    "23*x0 + 11*x3 >= 108",
    "7*x0 + 5*x2 >= 27",
    "5*x2 + 4*x3 >= 34",
    "21*x1 + 28*x2 >= 103",
    "9*x0 + 5*x3 >= 110",
    "9*x0 + 21*x1 + 28*x2 >= 75",
    "9*x0 + 28*x2 + 5*x3 >= 75",
    "9*x0 + 21*x1 + 28*x2 >= 146",
    "9*x0 + 28*x2 + 5*x3 >= 146",
    "23*x0 + 11*x3 <= 405",
    "4*x2 + 11*x3 <= 171",
    "27*x1 + 4*x2 <= 310",
    "23*x0 + 27*x1 <= 371",
    "23*x0 + 4*x2 <= 378",
    "23*x0 + 27*x1 + 4*x2 + 11*x3 <= 378",
    "2*x1 + 4*x3 <= 110",
    "7*x0 + 4*x3 <= 178",
    "7*x0 + 2*x1 + 5*x2 + 4*x3 <= 178",
    "21*x1 + 28*x2 <= 514",
    "9*x0 + 21*x1 <= 405",
    "9*x0 + 21*x1 + 28*x2 + 5*x3 <= 405",
    "23*x0 <= 543",
    "27*x1 <= 543",
    "4*x2 <= 543",
    "11*x3 <= 543",
    "7*x0 <= 246",
    "2*x1 <= 246",
    "5*x2 <= 246",
    "4*x3 <= 246",
    "9*x0 <= 597",
    "21*x1 <= 597",
    "28*x2 <= 597",
    "5*x3 <= 597"

  ]
}
```

```python
import gurobipy as gp

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

# Create variables
protein_bars = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="protein_bars")
granola_bars = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="granola_bars")
black_beans = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="black_beans")
chicken_breasts = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="chicken_breasts")

# Set objective function
m.setObjective(8 * protein_bars + 4 * granola_bars + 9 * black_beans + 2 * chicken_breasts, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(23 * protein_bars + 11 * chicken_breasts >= 108)
m.addConstr(7 * protein_bars + 5 * black_beans >= 27)
m.addConstr(5 * black_beans + 4 * chicken_breasts >= 34)
m.addConstr(21 * granola_bars + 28 * black_beans >= 103)
m.addConstr(9 * protein_bars + 5 * chicken_breasts >= 110)
m.addConstr(9 * protein_bars + 21 * granola_bars + 28 * black_beans >= 75)
m.addConstr(9 * protein_bars + 28 * black_beans + 5 * chicken_breasts >= 75)
m.addConstr(9 * protein_bars + 21 * granola_bars + 28 * black_beans >= 146)
m.addConstr(9 * protein_bars + 28 * black_beans + 5 * chicken_breasts >= 146)
m.addConstr(23 * protein_bars + 11 * chicken_breasts <= 405)
m.addConstr(4 * black_beans + 11 * chicken_breasts <= 171)
m.addConstr(27 * granola_bars + 4 * black_beans <= 310)
m.addConstr(23 * protein_bars + 27 * granola_bars <= 371)
m.addConstr(23 * protein_bars + 4 * black_beans <= 378)
m.addConstr(23 * protein_bars + 27 * granola_bars + 4 * black_beans + 11 * chicken_breasts <= 378)
m.addConstr(2 * granola_bars + 4 * chicken_breasts <= 110)
m.addConstr(7 * protein_bars + 4 * chicken_breasts <= 178)
m.addConstr(7 * protein_bars + 2 * granola_bars + 5 * black_beans + 4 * chicken_breasts <= 178)
m.addConstr(21 * granola_bars + 28 * black_beans <= 514)
m.addConstr(9 * protein_bars + 21 * granola_bars <= 405)
m.addConstr(9 * protein_bars + 21 * granola_bars + 28 * black_beans + 5 * chicken_breasts <= 405)


# Resource Constraints
m.addConstr(23 * protein_bars <= 543)
m.addConstr(27 * granola_bars <= 543)
m.addConstr(4 * black_beans <= 543)
m.addConstr(11 * chicken_breasts <= 543)
m.addConstr(7 * protein_bars <= 246)
m.addConstr(2 * granola_bars <= 246)
m.addConstr(5 * black_beans <= 246)
m.addConstr(4 * chicken_breasts <= 246)
m.addConstr(9 * protein_bars <= 597)
m.addConstr(21 * granola_bars <= 597)
m.addConstr(28 * black_beans <= 597)
m.addConstr(5 * chicken_breasts <= 597)



# 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("The model is infeasible.")
else:
    print("Optimization ended with status %d" % m.status)

```