```json
{
  "sym_variables": [
    ("x0", "rubber gloves"),
    ("x1", "cookies"),
    ("x2", "packs of napkins"),
    ("x3", "dish soap bottles")
  ],
  "objective_function": "3*x0 + 7*x1 + 7*x2 + 7*x3",
  "constraints": [
    "1.97*x0 + 0.95*x1 + 0.46*x2 + 0.64*x3 <= 144",
    "1.93*x0 + 1.77*x1 + 1.08*x2 + 0.4*x3 <= 136",
    "0.09*x0 + 1.49*x1 + 0.84*x2 + 0.96*x3 <= 213",
    "1.12*x0 + 1.23*x1 + 0.52*x2 + 0.04*x3 <= 108",
    "1.97*x0 + 0.46*x2 >= 27",
    "0.95*x1 + 0.46*x2 >= 26",
    "1.97*x0 + 0.64*x3 >= 16",
    "1.97*x0 + 0.95*x1 + 0.46*x2 + 0.64*x3 >= 16",
    "1.77*x1 + 0.4*x3 >= 14",
    "1.08*x2 + 0.4*x3 >= 24",
    "1.93*x0 + 1.77*x1 + 0.4*x3 >= 33",
    "1.93*x0 + 1.08*x2 + 0.4*x3 >= 33",
    "1.93*x0 + 1.77*x1 + 1.08*x2 >= 33",
    "1.93*x0 + 1.77*x1 + 0.4*x3 >= 32",
    "1.93*x0 + 1.08*x2 + 0.4*x3 >= 32",
    "1.93*x0 + 1.77*x1 + 1.08*x2 >= 32",
    "1.93*x0 + 1.77*x1 + 0.4*x3 >= 21",
    "1.93*x0 + 1.08*x2 + 0.4*x3 >= 21",
    "1.93*x0 + 1.77*x1 + 1.08*x2 >= 21",
    "1.93*x0 + 1.77*x1 + 1.08*x2 + 0.4*x3 >= 21",
    "0.09*x0 + 0.84*x2 >= 26",
    "0.84*x2 + 0.96*x3 >= 40",
    "0.09*x0 + 1.49*x1 >= 36",
    "1.49*x1 + 0.84*x2 >= 40",
    "0.09*x0 + 0.96*x3 >= 41",
    "0.09*x0 + 1.49*x1 + 0.84*x2 + 0.96*x3 >= 41",
    "1.23*x1 + 0.52*x2 >= 18",
    "1.12*x0 + 0.52*x2 >= 17",
    "1.12*x0 + 1.23*x1 + 0.52*x2 + 0.04*x3 >= 17",
    "9*x1 - x2 >= 0",
    "5*x0 - 2*x1 >= 0",
    "0.95*x1 + 0.46*x2 <= 39",
    "1.97*x0 + 0.95*x1 <= 135",
    "0.95*x1 + 0.64*x3 <= 138",
    "1.97*x0 + 0.46*x2 <= 120",
    "0.46*x2 + 0.64*x3 <= 137",
    "1.97*x0 + 0.95*x1 + 0.46*x2 <= 87",
    "1.93*x0 + 1.08*x2 + 0.4*x3 <= 67",
    "1.49*x1 + 0.84*x2 + 0.96*x3 <= 161",
    "0.09*x0 + 1.49*x1 + 0.84*x2 <= 211",
    "1.12*x0 + 0.52*x2 <= 38",
    "1.23*x1 + 0.04*x3 <= 30",
    "1.12*x0 + 1.23*x1 <= 95",
    "x0, x1, x2, x3 are integers"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
x0 = model.addVar(vtype=gp.GRB.INTEGER, name="rubber gloves")
x1 = model.addVar(vtype=gp.GRB.INTEGER, name="cookies")
x2 = model.addVar(vtype=gp.GRB.INTEGER, name="packs of napkins")
x3 = model.addVar(vtype=gp.GRB.INTEGER, name="dish soap bottles")


# Set objective function
model.setObjective(3*x0 + 7*x1 + 7*x2 + 7*x3, gp.GRB.MINIMIZE)

# Add constraints
model.addConstr(1.97*x0 + 0.95*x1 + 0.46*x2 + 0.64*x3 <= 144, "c1")
model.addConstr(1.93*x0 + 1.77*x1 + 1.08*x2 + 0.4*x3 <= 136, "c2")
model.addConstr(0.09*x0 + 1.49*x1 + 0.84*x2 + 0.96*x3 <= 213, "c3")
model.addConstr(1.12*x0 + 1.23*x1 + 0.52*x2 + 0.04*x3 <= 108, "c4")
model.addConstr(1.97*x0 + 0.46*x2 >= 27, "c5")
model.addConstr(0.95*x1 + 0.46*x2 >= 26, "c6")
model.addConstr(1.97*x0 + 0.64*x3 >= 16, "c7")
model.addConstr(1.97*x0 + 0.95*x1 + 0.46*x2 + 0.64*x3 >= 16, "c8")
model.addConstr(1.77*x1 + 0.4*x3 >= 14, "c9")
model.addConstr(1.08*x2 + 0.4*x3 >= 24, "c10")
model.addConstr(1.93*x0 + 1.77*x1 + 0.4*x3 >= 33, "c11")
model.addConstr(1.93*x0 + 1.08*x2 + 0.4*x3 >= 33, "c12")
model.addConstr(1.93*x0 + 1.77*x1 + 1.08*x2 >= 33, "c13")
model.addConstr(1.93*x0 + 1.77*x1 + 0.4*x3 >= 32, "c14")
model.addConstr(1.93*x0 + 1.08*x2 + 0.4*x3 >= 32, "c15")
model.addConstr(1.93*x0 + 1.77*x1 + 1.08*x2 >= 32, "c16")
model.addConstr(1.93*x0 + 1.77*x1 + 0.4*x3 >= 21, "c17")
model.addConstr(1.93*x0 + 1.08*x2 + 0.4*x3 >= 21, "c18")
model.addConstr(1.93*x0 + 1.77*x1 + 1.08*x2 >= 21, "c19")
model.addConstr(1.93*x0 + 1.77*x1 + 1.08*x2 + 0.4*x3 >= 21, "c20")
model.addConstr(0.09*x0 + 0.84*x2 >= 26, "c21")
model.addConstr(0.84*x2 + 0.96*x3 >= 40, "c22")
model.addConstr(0.09*x0 + 1.49*x1 >= 36, "c23")
model.addConstr(1.49*x1 + 0.84*x2 >= 40, "c24")
model.addConstr(0.09*x0 + 0.96*x3 >= 41, "c25")
model.addConstr(0.09*x0 + 1.49*x1 + 0.84*x2 + 0.96*x3 >= 41, "c26")
model.addConstr(1.23*x1 + 0.52*x2 >= 18, "c27")
model.addConstr(1.12*x0 + 0.52*x2 >= 17, "c28")
model.addConstr(1.12*x0 + 1.23*x1 + 0.52*x2 + 0.04*x3 >= 17, "c29")
model.addConstr(9*x1 - x2 >= 0, "c30")
model.addConstr(5*x0 - 2*x1 >= 0, "c31")
model.addConstr(0.95*x1 + 0.46*x2 <= 39, "c32")
model.addConstr(1.97*x0 + 0.95*x1 <= 135, "c33")
model.addConstr(0.95*x1 + 0.64*x3 <= 138, "c34")
model.addConstr(1.97*x0 + 0.46*x2 <= 120, "c35")
model.addConstr(0.46*x2 + 0.64*x3 <= 137, "c36")
model.addConstr(1.97*x0 + 0.95*x1 + 0.46*x2 <= 87, "c37")
model.addConstr(1.93*x0 + 1.08*x2 + 0.4*x3 <= 67, "c38")
model.addConstr(1.49*x1 + 0.84*x2 + 0.96*x3 <= 161, "c39")
model.addConstr(0.09*x0 + 1.49*x1 + 0.84*x2 <= 211, "c40")
model.addConstr(1.12*x0 + 0.52*x2 <= 38, "c41")
model.addConstr(1.23*x1 + 0.04*x3 <= 30, "c42")
model.addConstr(1.12*x0 + 1.23*x1 <= 95, "c43")


# Optimize model
model.optimize()

# Print results
if model.status == gp.GRB.OPTIMAL:
    print('Obj: %g' % model.objVal)
    for v in model.getVars():
        print('%s %g' % (v.varName, v.x))
elif model.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {model.status}")

```
