```json
{
  "sym_variables": [
    ("x0", "hours worked by Dale"),
    ("x1", "hours worked by Paul"),
    ("x2", "hours worked by Laura"),
    ("x3", "hours worked by John")
  ],
  "objective_function": "9.78*x0 + 3.35*x1 + 4.5*x2 + 4.6*x3",
  "constraints": [
    "9*x0 + 12*x2 >= 65",
    "9*x0 + 9*x3 >= 40",
    "9*x0 + 9*x1 >= 44",
    "9*x1 + 9*x3 >= 65",
    "9*x1 + 12*x2 >= 34",
    "9*x0 + 9*x1 + 12*x2 >= 55",
    "9*x0 + 12*x2 + 9*x3 >= 55",
    "9*x1 + 12*x2 + 9*x3 >= 55",
    "9*x0 + 9*x1 + 12*x2 >= 63",
    "9*x0 + 12*x2 + 9*x3 >= 63",
    "9*x1 + 12*x2 + 9*x3 >= 63",
    "9*x0 + 9*x1 + 12*x2 >= 44",
    "9*x0 + 12*x2 + 9*x3 >= 44",
    "9*x1 + 12*x2 + 9*x3 >= 44",
    "9*x0 + 9*x1 + 12*x2 + 9*x3 >= 44",
    "9*x0 + 10*x2 >= 68",
    "11*x1 + 11*x3 >= 66",
    "9*x0 + 11*x1 >= 76",
    "9*x0 + 10*x2 + 11*x3 >= 76",
    "9*x0 + 11*x1 + 10*x2 + 11*x3 >= 76",
    "6*x1 + 2*x2 >= 13",
    "2*x2 + 11*x3 >= 13",
    "11*x0 + 2*x2 >= 18",
    "11*x0 + 6*x1 + 2*x2 + 11*x3 >= 18",
    "-10*x2 + 3*x3 >= 0",
    "9*x1 + 9*x3 <= 169",
    "9*x0 + 12*x2 <= 178",
    "9*x0 + 9*x1 <= 228",
    "9*x1 + 12*x2 + 9*x3 <= 91",
    "9*x0 + 11*x1 + 11*x3 <= 86",
    "6*x1 + 2*x2 + 11*x3 <= 26",
    "11*x0 + 2*x2 + 11*x3 <= 62"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
dale_hours = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="Dale_hours")
paul_hours = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="Paul_hours")
laura_hours = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="Laura_hours")
john_hours = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="John_hours")


# Set objective function
m.setObjective(9.78 * dale_hours + 3.35 * paul_hours + 4.5 * laura_hours + 4.6 * john_hours, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(9 * dale_hours + 12 * laura_hours >= 65)
m.addConstr(9 * dale_hours + 9 * john_hours >= 40)
m.addConstr(9 * dale_hours + 9 * paul_hours >= 44)
m.addConstr(9 * paul_hours + 9 * john_hours >= 65)
m.addConstr(9 * paul_hours + 12 * laura_hours >= 34)
m.addConstr(9 * dale_hours + 9 * paul_hours + 12 * laura_hours >= 55)
m.addConstr(9 * dale_hours + 12 * laura_hours + 9 * john_hours >= 55)
m.addConstr(9 * paul_hours + 12 * laura_hours + 9 * john_hours >= 55)
m.addConstr(9 * dale_hours + 9 * paul_hours + 12 * laura_hours >= 63)
m.addConstr(9 * dale_hours + 12 * laura_hours + 9 * john_hours >= 63)
m.addConstr(9 * paul_hours + 12 * laura_hours + 9 * john_hours >= 63)
m.addConstr(9 * dale_hours + 9 * paul_hours + 12 * laura_hours >= 44)
m.addConstr(9 * dale_hours + 12 * laura_hours + 9 * john_hours >= 44)
m.addConstr(9 * paul_hours + 12 * laura_hours + 9 * john_hours >= 44)
m.addConstr(9 * dale_hours + 9 * paul_hours + 12 * laura_hours + 9 * john_hours >= 44)
m.addConstr(9 * dale_hours + 10 * laura_hours >= 68)
m.addConstr(11 * paul_hours + 11 * john_hours >= 66)
m.addConstr(9 * dale_hours + 11 * paul_hours >= 76)
m.addConstr(9 * dale_hours + 10 * laura_hours + 11 * john_hours >= 76)
m.addConstr(9 * dale_hours + 11 * paul_hours + 10 * laura_hours + 11 * john_hours >= 76)
m.addConstr(6 * paul_hours + 2 * laura_hours >= 13)
m.addConstr(2 * laura_hours + 11 * john_hours >= 13)
m.addConstr(11 * dale_hours + 2 * laura_hours >= 18)
m.addConstr(11 * dale_hours + 6 * paul_hours + 2 * laura_hours + 11 * john_hours >= 18)
m.addConstr(-10 * laura_hours + 3 * john_hours >= 0)
m.addConstr(9 * paul_hours + 9 * john_hours <= 169)
m.addConstr(9 * dale_hours + 12 * laura_hours <= 178)
m.addConstr(9 * dale_hours + 9 * paul_hours <= 228)
m.addConstr(9 * paul_hours + 12 * laura_hours + 9 * john_hours <= 91)
m.addConstr(9 * dale_hours + 11 * paul_hours + 11 * john_hours <= 86)
m.addConstr(6 * paul_hours + 2 * laura_hours + 11 * john_hours <= 26)
m.addConstr(11 * dale_hours + 2 * laura_hours + 11 * john_hours <= 62)


# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print(f"Optimal objective value: {m.objVal}")
    for v in m.getVars():
        print(f"{v.varName}: {v.x}")
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization terminated with status {m.status}")

```