## Problem Description and Formulation

The problem is a classic example of a linear programming problem. The goal is to maximize the profit of Tom Bakery by determining the optimal number of batches of pancakes and pretzels to produce, given the constraints on oven time and pastry chef time.

Let's define the decision variables:

* $x_1$: number of batches of pancakes
* $x_2$: number of batches of pretzels

The objective function is to maximize the profit:

* Profit per batch of pancakes: $25
* Profit per batch of pretzels: $50

The constraints are:

* Oven time: 2.5 hours per batch of pancakes, 1.5 hours per batch of pretzels, and at most 65 hours available
* Pastry chef time: 0.5 hours per batch of pancakes, 3 hours per batch of pretzels, and at most 35 hours available

## Mathematical Formulation

The mathematical formulation of the problem is:

Maximize:

$$25x_1 + 50x_2$$

Subject to:

$$2.5x_1 + 1.5x_2 \leq 65$$
$$0.5x_1 + 3x_2 \leq 35$$
$$x_1, x_2 \geq 0$$

## Gurobi Code

```python
import gurobi

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

# Define the decision variables
x1 = m.addVar(name="pancakes", lb=0, ub=None, obj=25)
x2 = m.addVar(name="pretzels", lb=0, ub=None, obj=50)

# Add the oven time constraint
m.addConstr(2.5 * x1 + 1.5 * x2 <= 65, name="oven_time")

# Add the pastry chef time constraint
m.addConstr(0.5 * x1 + 3 * x2 <= 35, name="pastry_chef_time")

# Set the model objective to maximize profit
m.setObjective(x1.obj * x1 + x2.obj * x2, gurobi.GRB.MAXIMIZE)

# Optimize the model
m.optimize()

# Print the solution
if m.status == gurobi.GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Number of batches of pancakes: {x1.x}")
    print(f"Number of batches of pretzels: {x2.x}")
    print(f"Maximum profit: ${m.objVal:.2f}")
else:
    print("No optimal solution found.")
```