## Step 1: Define the symbolic representation of the variables
The variables are 'smoke detectors', 'rubber bands', 'yellow highlighters', and 'cafeteria chairs', which can be represented symbolically as $x_0, x_1, x_2, x_3$ respectively.

## Step 2: Convert the objective function into a symbolic representation
The objective function to maximize is $8.31x_0 + 6.4x_1 + 4.26x_2 + 1.25x_3$.

## Step 3: List all the constraints in symbolic notation
1. $x_0 \geq 0$ (non-negativity constraint, implicitly handled by Gurobi for integer variables)
2. $x_1 \geq 0$ (non-negativity constraint, implicitly handled by Gurobi for integer variables)
3. $x_2 \geq 0$ (non-negativity constraint, implicitly handled by Gurobi for integer variables)
4. $x_3 \geq 0$ (non-negativity constraint, implicitly handled by Gurobi for integer variables)
5. $1x_0 + 6x_1 + 7x_2 \geq 34$ (minimum spend on smoke detectors, rubber bands, and yellow highlighters)
6. $2x_2 + 7x_3 \geq 21$ (minimum storage space for yellow highlighters and cafeteria chairs)
7. $2x_0 + 7x_1 \geq 32$ (minimum storage space for smoke detectors and rubber bands)
8. $2x_0 + 7x_1 + 7x_3 \geq 25$ (minimum storage space for smoke detectors, rubber bands, and cafeteria chairs)
9. $7x_2 + 2x_3 \leq 67$ (maximum cost for yellow highlighters and cafeteria chairs)
10. $1x_0 + 6x_1 \leq 159$ (maximum cost for smoke detectors and rubber bands)
11. $6x_1 + 2x_3 \leq 126$ (maximum spend on rubber bands and cafeteria chairs)
12. $1x_0 + 6x_1 + 7x_2 + 2x_3 \leq 126$ (maximum total spend)
13. $2x_0 + 7x_1 \leq 69$ (maximum storage space for smoke detectors and rubber bands)
14. $7x_1 + 7x_3 \leq 51$ (maximum storage space for rubber bands and cafeteria chairs)
15. $7x_1 + 2x_2 \leq 61$ (maximum storage space for rubber bands and yellow highlighters)
16. $7x_1 + 2x_2 + 7x_3 \leq 36$ (maximum storage space for rubber bands, yellow highlighters, and cafeteria chairs)
17. $2x_0 + 2x_2 + 7x_3 \leq 109$ (maximum storage space for smoke detectors, yellow highlighters, and cafeteria chairs)
18. $2x_0 + 7x_1 + 2x_2 + 7x_3 \leq 109$ (maximum total storage space)

## 4: Define the symbolic representation of the problem
```json
{
    'sym_variables': [
        ('x0', 'smoke detectors'), 
        ('x1', 'rubber bands'), 
        ('x2', 'yellow highlighters'), 
        ('x3', 'cafeteria chairs')
    ], 
    'objective_function': '8.31x0 + 6.4x1 + 4.26x2 + 1.25x3', 
    'constraints': [
        'x0 + 6x1 + 7x2 >= 34',
        '2x2 + 7x3 >= 21',
        '2x0 + 7x1 >= 32',
        '2x0 + 7x1 + 7x3 >= 25',
        '7x2 + 2x3 <= 67',
        'x0 + 6x1 <= 159',
        '6x1 + 2x3 <= 126',
        'x0 + 6x1 + 7x2 + 2x3 <= 126',
        '2x0 + 7x1 <= 69',
        '7x1 + 7x3 <= 51',
        '7x1 + 2x2 <= 61',
        '7x1 + 2x2 + 7x3 <= 36',
        '2x0 + 2x2 + 7x3 <= 109',
        '2x0 + 7x1 + 2x2 + 7x3 <= 109'
    ]
}
```

## 5: Implement the optimization problem using Gurobi
```python
import gurobi

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

    # Define the variables
    x0 = model.addVar(name="smoke detectors", vtype=gurobi.GRB.INTEGER)
    x1 = model.addVar(name="rubber bands", vtype=gurobi.GRB.INTEGER)
    x2 = model.addVar(name="yellow highlighters", vtype=gurobi.GRB.INTEGER)
    x3 = model.addVar(name="cafeteria chairs", vtype=gurobi.GRB.INTEGER)

    # Define the objective function
    model.setObjective(8.31 * x0 + 6.4 * x1 + 4.26 * x2 + 1.25 * x3, gurobi.GRB.MAXIMIZE)

    # Add constraints
    model.addConstr(x0 + 6 * x1 + 7 * x2 >= 34, name="min_spend_1")
    model.addConstr(2 * x2 + 7 * x3 >= 21, name="min_storage_1")
    model.addConstr(2 * x0 + 7 * x1 >= 32, name="min_storage_2")
    model.addConstr(2 * x0 + 7 * x1 + 7 * x3 >= 25, name="min_storage_3")
    model.addConstr(7 * x2 + 2 * x3 <= 67, name="max_cost_1")
    model.addConstr(x0 + 6 * x1 <= 159, name="max_cost_2")
    model.addConstr(6 * x1 + 2 * x3 <= 126, name="max_spend_1")
    model.addConstr(x0 + 6 * x1 + 7 * x2 + 2 * x3 <= 126, name="max_total_spend")
    model.addConstr(2 * x0 + 7 * x1 <= 69, name="max_storage_1")
    model.addConstr(7 * x1 + 7 * x3 <= 51, name="max_storage_2")
    model.addConstr(7 * x1 + 2 * x2 <= 61, name="max_storage_3")
    model.addConstr(7 * x1 + 2 * x2 + 7 * x3 <= 36, name="max_storage_4")
    model.addConstr(2 * x0 + 2 * x2 + 7 * x3 <= 109, name="max_storage_5")
    model.addConstr(2 * x0 + 7 * x1 + 2 * x2 + 7 * x3 <= 109, name="max_total_storage")

    # Solve the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print("Optimal solution found.")
        print(f"Smoke detectors: {x0.varValue}")
        print(f"Rubber bands: {x1.varValue}")
        print(f"Yellow highlighters: {x2.varValue}")
        print(f"Cafeteria chairs: {x3.varValue}")
        print(f"Objective: {model.objVal}")
    else:
        print("No optimal solution found.")

solve_optimization_problem()
```