## Problem Description and Formulation

The problem requires minimizing the objective function: $5 \times \text{rubber bands} + 7 \times \text{monochrome printers} + 4 \times \text{cans of coffee}$.

Subject to the following constraints:

1. Usefulness ratings: 
   - Rubber bands: 19
   - Monochrome printers: 2
   - Cans of coffee: 9

2. Constraints on usefulness ratings:
   - $\text{Rubber bands} \times 19 + \text{Cans of coffee} \times 9 \geq 67$
   - $\text{Monochrome printers} \times 2 + \text{Cans of coffee} \times 9 \geq 105$
   - $\text{Rubber bands} \times 19 + \text{Monochrome printers} \times 2 \geq 61$
   - $\text{Rubber bands} \times 19 + \text{Monochrome printers} \times 2 + \text{Cans of coffee} \times 9 \geq 67$

3. Additional constraints:
   - $-8 \times \text{rubber bands} + 5 \times \text{cans of coffee} \geq 0$
   - $-\text{monochrome printers} + 8 \times \text{cans of coffee} \geq 0$

4. Upper bounds on usefulness ratings:
   - $\text{Rubber bands} \times 19 + \text{Cans of coffee} \times 9 \leq 311$
   - $\text{Rubber bands} \times 19 + \text{Monochrome printers} \times 2 \leq 174$

5. Variable constraints:
   - $\text{rubber bands}$, $\text{monochrome printers}$, and $\text{cans of coffee}$ must be integers.

## Gurobi Code Formulation

```python
import gurobi

def solve_optimization_problem():
    # Create a new Gurobi model
    model = gurobi.Model()

    # Define variables
    rubber_bands = model.addVar(name="rubber_bands", vtype=gurobi.GRB.INTEGER)
    monochrome_printers = model.addVar(name="monochrome_printers", vtype=gurobi.GRB.INTEGER)
    cans_of_coffee = model.addVar(name="cans_of_coffee", vtype=gurobi.GRB.INTEGER)

    # Objective function
    model.setObjective(5 * rubber_bands + 7 * monochrome_printers + 4 * cans_of_coffee, gurobi.GRB.MINIMIZE)

    # Constraints
    model.addConstr(19 * rubber_bands + 9 * cans_of_coffee >= 67)
    model.addConstr(2 * monochrome_printers + 9 * cans_of_coffee >= 105)
    model.addConstr(19 * rubber_bands + 2 * monochrome_printers >= 61)
    model.addConstr(19 * rubber_bands + 2 * monochrome_printers + 9 * cans_of_coffee >= 67)

    model.addConstr(-8 * rubber_bands + 5 * cans_of_coffee >= 0)
    model.addConstr(-monochrome_printers + 8 * cans_of_coffee >= 0)

    model.addConstr(19 * rubber_bands + 9 * cans_of_coffee <= 311)
    model.addConstr(19 * rubber_bands + 2 * monochrome_printers <= 174)

    # Solve the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print("Optimal solution found.")
        print(f"Rubber bands: {rubber_bands.varValue}")
        print(f"Monochrome printers: {monochrome_printers.varValue}")
        print(f"Cans of coffee: {cans_of_coffee.varValue}")
        print(f"Objective function value: {model.objVal}")
    elif model.status == gurobi.GRB.INFEASIBLE:
        print("The model is infeasible.")
    else:
        print("The model has a non-optimal status.")

solve_optimization_problem()
```