```json
{
  "sym_variables": [
    ("x0", "red pens"),
    ("x1", "black pens"),
    ("x2", "rubber bands"),
    ("x3", "3D printers"),
    ("x4", "smoke detectors")
  ],
  "objective_function": "8*x0 + 6*x1 + 5*x2 + 8*x3 + 1*x4",
  "constraints": [
    "3*x3 + 3*x4 >= 20",
    "3*x0 + 3*x4 >= 29",
    "3*x2 + 8*x3 >= 54",
    "6*x1 + 3*x4 >= 50",
    "6*x1 + 8*x3 + 3*x4 >= 32",
    "3*x0 + 8*x3 + 3*x4 >= 32",
    "6*x1 + 3*x2 + 3*x4 >= 32",
    "6*x1 + 8*x3 + 3*x4 >= 30",
    "3*x0 + 8*x3 + 3*x4 >= 30",
    "6*x1 + 3*x2 + 3*x4 >= 30",
    "6*x1 + 8*x3 + 3*x4 >= 35",
    "3*x0 + 8*x3 + 3*x4 >= 35",
    "6*x1 + 3*x2 + 3*x4 >= 35",
    "5*x0 + 9*x1 + 3*x3 >= 21",
    "5*x0 + 9*x1 + 5*x2 >= 21",
    "5*x2 + 3*x3 + 1*x4 >= 21",
    "5*x0 + 9*x1 + 1*x4 >= 21",
    "5*x0 + 9*x1 + 3*x3 >= 17",
    "5*x0 + 9*x1 + 5*x2 >= 17",
    "5*x2 + 3*x3 + 1*x4 >= 17",
    "5*x0 + 9*x1 + 1*x4 >= 17",
    "5*x0 + 9*x1 + 3*x3 >= 16",
    "5*x0 + 9*x1 + 5*x2 >= 16",
    "5*x2 + 3*x3 + 1*x4 >= 16",
    "5*x0 + 9*x1 + 1*x4 >= 16",
    "5*x0 + 9*x1 + 3*x3 >= 21",
    "5*x0 + 9*x1 + 5*x2 >= 21",
    "5*x2 + 3*x3 + 1*x4 >= 21",
    "5*x0 + 9*x1 + 1*x4 >= 21",
    "2*x1 + 5*x4 >= 46",
    "5*x2 + 1*x3 >= 27",
    "3*x0 + 2*x1 >= 36",
    "3*x0 + 5*x4 >= 27",
    "3*x0 + 1*x3 + 5*x4 >= 42",
    "3*x0 + 5*x2 + 1*x3 >= 42",
    "3*x0 + 1*x3 + 5*x4 >= 58",
    "3*x0 + 5*x2 + 1*x3 >= 58",
    "4*x0 + 3*x2 - 8*x4 >= 0",
    "3*x2 + 8*x3 <= 60",
    "3*x0 + 3*x4 <= 258",
    "3*x0 + 3*x2 <= 237",
    "3*x2 + 3*x4 <= 160",
    "6*x1 + 3*x2 <= 152",
    "8*x3 + 3*x4 <= 121",
    "6*x1 + 3*x4 <= 182",
    "3*x0 + 6*x1 + 3*x2 + 8*x3 + 3*x4 <= 182",
    "5*x0 + 5*x2 <= 42",
    "3*x3 + 1*x4 <= 27",
    "5*x2 + 3*x3 <= 80",
    "9*x1 + 1*x4 <= 92",
    "5*x0 + 9*x1 <= 103",
    "9*x1 + 5*x2 <= 96",
    "9*x1 + 3*x3 + 1*x4 <= 30",
    "9*x1 + 5*x2 + 1*x4 <= 65",
    "5*x0 + 9*x1 + 5*x2 + 3*x3 + 1*x4 <= 65",
    "3*x0 + 5*x2 <= 142",
    "3*x0 + 5*x4 <= 309",
    "2*x1 + 1*x3 <= 117",
    "2*x1 + 5*x4 <= 135",
    "3*x0 + 2*x1 + 1*x3 <= 91",
    "3*x0 + 5*x2 + 1*x3 <= 176",
    "2*x1 + 5*x2 + 5*x4 <= 211",
    "3*x0 + 2*x1 + 5*x2 + 1*x3 + 5*x4 <= 211"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
red_pens = m.addVar(vtype=gp.GRB.INTEGER, name="red_pens")
black_pens = m.addVar(vtype=gp.GRB.INTEGER, name="black_pens")
rubber_bands = m.addVar(vtype=gp.GRB.INTEGER, name="rubber_bands")
printers_3d = m.addVar(vtype=gp.GRB.INTEGER, name="3D_printers")
smoke_detectors = m.addVar(vtype=gp.GRB.INTEGER, name="smoke_detectors")


# Set objective function
m.setObjective(8 * red_pens + 6 * black_pens + 5 * rubber_bands + 8 * printers_3d + 1 * smoke_detectors, gp.GRB.MAXIMIZE)

# Add constraints
m.addConstr(3 * printers_3d + 3 * smoke_detectors >= 20)
m.addConstr(3 * red_pens + 3 * smoke_detectors >= 29)
m.addConstr(3 * rubber_bands + 8 * printers_3d >= 54)
m.addConstr(6 * black_pens + 3 * smoke_detectors >= 50)
m.addConstr(6 * black_pens + 8 * printers_3d + 3 * smoke_detectors >= 32)
m.addConstr(3 * red_pens + 8 * printers_3d + 3 * smoke_detectors >= 32)
m.addConstr(6 * black_pens + 3 * rubber_bands + 3 * smoke_detectors >= 32)
m.addConstr(6 * black_pens + 8 * printers_3d + 3 * smoke_detectors >= 30)
m.addConstr(3 * red_pens + 8 * printers_3d + 3 * smoke_detectors >= 30)
m.addConstr(6 * black_pens + 3 * rubber_bands + 3 * smoke_detectors >= 30)
m.addConstr(6 * black_pens + 8 * printers_3d + 3 * smoke_detectors >= 35)
m.addConstr(3 * red_pens + 8 * printers_3d + 3 * smoke_detectors >= 35)
m.addConstr(6 * black_pens + 3 * rubber_bands + 3 * smoke_detectors >= 35)
m.addConstr(5 * red_pens + 9 * black_pens + 3 * printers_3d >= 21)
m.addConstr(5 * red_pens + 9 * black_pens + 5 * rubber_bands >= 21)
m.addConstr(5 * rubber_bands + 3 * printers_3d + 1 * smoke_detectors >= 21)
m.addConstr(5 * red_pens + 9 * black_pens + 1 * smoke_detectors >= 21)

# ... (rest of the constraints)


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

```