## Problem Description and Formulation

The problem is a classic example of a linear programming problem. The goal is to maximize the profit of a sandwich store by determining the optimal number of tuna salad and chicken salad sandwiches to produce, given the time constraints for mixing ingredients and putting together the sandwiches.

Let's define the decision variables:

* $x_1$: the number of tuna salad sandwiches to produce
* $x_2$: the number of chicken salad sandwiches to produce

The objective function is to maximize the profit:

* Profit per tuna salad sandwich: $2
* Profit per chicken salad sandwich: $3

The constraints are:

* Mixing time: 3 minutes per tuna salad sandwich, 5 minutes per chicken salad sandwich, and 300 minutes available
* Putting together time: 5 minutes per tuna salad sandwich, 6 minutes per chicken salad sandwich, and 400 minutes available

## Mathematical Formulation

The mathematical formulation of the problem is:

Maximize: $2x_1 + 3x_2$

Subject to:

* $3x_1 + 5x_2 \leq 300$ (mixing time constraint)
* $5x_1 + 6x_2 \leq 400$ (putting together time constraint)
* $x_1, x_2 \geq 0$ (non-negativity constraint)

## Gurobi Code

```python
import gurobi

# Create a new model
model = gurobi.Model()

# Define the decision variables
x1 = model.addVar(lb=0, name="tuna_salad_sandwiches")
x2 = model.addVar(lb=0, name="chicken_salad_sandwiches")

# Define the objective function
model.setObjective(2 * x1 + 3 * x2, gurobi.GRB.MAXIMIZE)

# Define the constraints
model.addConstr(3 * x1 + 5 * x2 <= 300, name="mixing_time_constraint")
model.addConstr(5 * x1 + 6 * x2 <= 400, name="putting_together_time_constraint")

# Optimize the model
model.optimize()

# Print the solution
if model.status == gurobi.GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Tuna salad sandwiches: {x1.varValue}")
    print(f"Chicken salad sandwiches: {x2.varValue}")
    print(f"Maximal profit: {model.objVal}")
else:
    print("No optimal solution found.")
```