## Problem Description and Formulation

The problem is a linear programming optimization problem. The goal is to maximize the profit of a sandwich store by determining the number of peanut butter sandwiches and chocolate spread sandwiches to sell.

### Decision Variables

* $x$: Number of peanut butter sandwiches to sell
* $y$: Number of chocolate spread sandwiches to sell

### Objective Function

The profit per peanut butter sandwich is $3, and the profit per chocolate spread sandwich is $2. The objective function to maximize is:

Maximize: $3x + 2y$

### Constraints

1. The store only has enough bread to make at most 150 sandwiches: $x + y \leq 150$
2. The store must sell at least 45 peanut butter sandwiches: $x \geq 45$
3. The store must sell at least 65 chocolate spread sandwiches: $y \geq 65$
4. The store only has enough spread, peanut butter, and chocolate to make at most 80 peanut butter sandwiches: $x \leq 80$
5. The store only has enough spread, peanut butter, and chocolate to make at most 100 chocolate spread sandwiches: $y \leq 100$

### Gurobi Code

```python
import gurobi

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

    # Define decision variables
    x = model.addVar(lb=0, ub=150, name="peanut_butter_sandwiches")
    y = model.addVar(lb=0, ub=150, name="chocolate_spread_sandwiches")

    # Set bounds based on problem constraints
    x.lb = 45
    y.lb = 65
    x.ub = 80
    y.ub = 100

    # Objective function: Maximize 3x + 2y
    model.setObjective(3 * x + 2 * y, gurobi.GRB.MAXIMIZE)

    # Add constraints
    model.addConstr(x + y <= 150, name="bread_constraint")

    # Solve the model
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: x = {x.varValue}, y = {y.varValue}")
        print(f"Maximum profit: ${3 * x.varValue + 2 * y.varValue}")
    else:
        print("No optimal solution found")

solve_sandwich_problem()
```

However, a more idiomatic way to write this would be 

```python
import gurobi

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

    # Define decision variables
    x = model.addVar(lb=45, ub=80, name="peanut_butter_sandwiches")
    y = model.addVar(lb=65, ub=100, name="chocolate_spread_sandwiches")

    # Objective function: Maximize 3x + 2y
    model.setObjective(3 * x + 2 * y, gurobi.GRB.MAXIMIZE)

    # Add constraints
    model.addConstr(x + y <= 150, name="bread_constraint")

    # Solve the model
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: x = {x.varValue}, y = {y.varValue}")
        print(f"Maximum profit: ${3 * x.varValue + 2 * y.varValue}")
    else:
        print("No optimal solution found")

solve_sandwich_problem()
```