```json
{
  "sym_variables": [
    ("x0", "scissors"),
    ("x1", "color printers")
  ],
  "objective_function": "9.7 * x0 + 3.74 * x1",
  "constraints": [
    "1 * x0 + 19 * x1 >= 45",
    "30 * x0 + 7 * x1 >= 119",
    "21 * x0 + 23 * x1 >= 36",
    "-7 * x0 + 7 * x1 >= 0",
    "1 * x0 + 19 * x1 <= 105",
    "30 * x0 + 7 * x1 <= 319",
    "21 * x0 + 23 * x1 <= 83"
  ]
}
```

```python
import gurobipy as gp

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

    # Create variables
    scissors = m.addVar(vtype=gp.GRB.INTEGER, name="scissors")
    color_printers = m.addVar(vtype=gp.GRB.INTEGER, name="color_printers")

    # Set objective function
    m.setObjective(9.7 * scissors + 3.74 * color_printers, gp.GRB.MINIMIZE)

    # Add constraints
    m.addConstr(1 * scissors + 19 * color_printers >= 45, "cost_lower_bound")
    m.addConstr(30 * scissors + 7 * color_printers >= 119, "usefulness_lower_bound")
    m.addConstr(21 * scissors + 23 * color_printers >= 36, "sustainability_lower_bound")
    m.addConstr(-7 * scissors + 7 * color_printers >= 0, "scissors_printers_relation")
    m.addConstr(1 * scissors + 19 * color_printers <= 105, "cost_upper_bound")
    m.addConstr(30 * scissors + 7 * color_printers <= 319, "usefulness_upper_bound")
    m.addConstr(21 * scissors + 23 * color_printers <= 83, "sustainability_upper_bound")


    # Optimize model
    m.optimize()

    # Print results
    if m.status == gp.GRB.OPTIMAL:
        print('Obj: %g' % m.objVal)
        print('scissors:', scissors.x)
        print('color_printers:', color_printers.x)
    elif m.status == gp.GRB.INFEASIBLE:
        print('The model is infeasible.')
    else:
        print('Optimization ended with status %d' % m.status)


except gp.GurobiError as e:
    print('Error code ' + str(e.errno) + ': ' + str(e))

except AttributeError:
    print('Encountered an attribute error')
```