```json
{
  "sym_variables": [
    ("x0", "hours worked by Paul"),
    ("x1", "hours worked by Peggy"),
    ("x2", "hours worked by Jean"),
    ("x3", "hours worked by Dale")
  ],
  "objective_function": "2.91 * x0 + 4.55 * x1 + 2.66 * x2 + 5.97 * x3",
  "constraints": [
    "8 * x1 + 11 * x3 >= 71",
    "9 * x0 + 11 * x3 >= 39",
    "9 * x0 + 8 * x1 >= 61",
    "9 * x0 + 8 * x1 + 27 * x2 >= 72",
    "9 * x0 + 27 * x2 + 11 * x3 >= 72",
    "8 * x1 + 27 * x2 + 11 * x3 >= 72",
    "9 * x0 + 8 * x1 + 27 * x2 >= 52",
    "9 * x0 + 27 * x2 + 11 * x3 >= 52",
    "8 * x1 + 27 * x2 + 11 * x3 >= 52",
    "9 * x0 + 8 * x1 + 27 * x2 >= 66",
    "9 * x0 + 27 * x2 + 11 * x3 >= 66",
    "8 * x1 + 27 * x2 + 11 * x3 >= 66",
    "9 * x0 + 8 * x1 + 27 * x2 + 11 * x3 >= 66",
    "26 * x1 + 31 * x2 >= 45",
    "26 * x1 + 9 * x3 >= 50",
    "26 * x1 + 31 * x2 + 9 * x3 >= 56",
    "10 * x0 + 26 * x1 + 31 * x2 + 9 * x3 >= 56",
    "7 * x0 + 24 * x1 >= 87",
    "29 * x2 + 29 * x3 >= 37",
    "7 * x0 + 29 * x2 >= 34",
    "7 * x0 + 29 * x3 >= 34",
    "7 * x0 + 24 * x1 + 29 * x2 + 29 * x3 >= 34",
    "4 * x0 - x1 >= 0",
    "9 * x0 + 8 * x1 <= 209",
    "8 * x1 + 11 * x3 <= 209",
    "8 * x1 + 27 * x2 <= 78",
    "9 * x0 + 27 * x2 <= 269",
    "9 * x0 + 11 * x3 <= 176",
    "9 * x0 + 8 * x1 + 11 * x3 <= 109",
    "9 * x0 + 27 * x2 + 11 * x3 <= 108",
    "10 * x0 + 31 * x2 <= 109",
    "26 * x1 + 9 * x3 <= 138",
    "10 * x0 + 31 * x2 + 9 * x3 <= 167",
    "26 * x1 + 31 * x2 + 9 * x3 <= 177",
    "10 * x0 + 26 * x1 + 31 * x2 <= 93",
    "x0 >= 0",
    "x1 >= 0",
    "x2 >= 0",
    "x3 >= 0"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
paul = m.addVar(lb=0, name="Paul")
peggy = m.addVar(lb=0, name="Peggy")
jean = m.addVar(lb=0, name="Jean")
dale = m.addVar(lb=0, name="Dale")


# Set objective function
m.setObjective(2.91 * paul + 4.55 * peggy + 2.66 * jean + 5.97 * dale, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(8 * peggy + 11 * dale >= 71)
m.addConstr(9 * paul + 11 * dale >= 39)
m.addConstr(9 * paul + 8 * peggy >= 61)
m.addConstr(9 * paul + 8 * peggy + 27 * jean >= 72)
m.addConstr(9 * paul + 27 * jean + 11 * dale >= 72)
m.addConstr(8 * peggy + 27 * jean + 11 * dale >= 72)
m.addConstr(9 * paul + 8 * peggy + 27 * jean >= 52)
m.addConstr(9 * paul + 27 * jean + 11 * dale >= 52)
m.addConstr(8 * peggy + 27 * jean + 11 * dale >= 52)
m.addConstr(9 * paul + 8 * peggy + 27 * jean >= 66)
m.addConstr(9 * paul + 27 * jean + 11 * dale >= 66)
m.addConstr(8 * peggy + 27 * jean + 11 * dale >= 66)
m.addConstr(9 * paul + 8 * peggy + 27 * jean + 11 * dale >= 66)
m.addConstr(26 * peggy + 31 * jean >= 45)
m.addConstr(26 * peggy + 9 * dale >= 50)
m.addConstr(26 * peggy + 31 * jean + 9 * dale >= 56)
m.addConstr(10 * paul + 26 * peggy + 31 * jean + 9 * dale >= 56)
m.addConstr(7 * paul + 24 * peggy >= 87)
m.addConstr(29 * jean + 29 * dale >= 37)
m.addConstr(7 * paul + 29 * jean >= 34)
m.addConstr(7 * paul + 29 * dale >= 34)
m.addConstr(7 * paul + 24 * peggy + 29 * jean + 29 * dale >= 34)
m.addConstr(4 * paul - peggy >= 0)
m.addConstr(9 * paul + 8 * peggy <= 209)
m.addConstr(8 * peggy + 11 * dale <= 209)
m.addConstr(8 * peggy + 27 * jean <= 78)
m.addConstr(9 * paul + 27 * jean <= 269)
m.addConstr(9 * paul + 11 * dale <= 176)
m.addConstr(9 * paul + 8 * peggy + 11 * dale <= 109)
m.addConstr(9 * paul + 27 * jean + 11 * dale <= 108)
m.addConstr(10 * paul + 31 * jean <= 109)
m.addConstr(26 * peggy + 9 * dale <= 138)
m.addConstr(10 * paul + 31 * jean + 9 * dale <= 167)
m.addConstr(26 * peggy + 31 * jean + 9 * dale <= 177)
m.addConstr(10 * paul + 26 * peggy + 31 * jean <= 93)


# Optimize model
m.optimize()

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

```
