## Problem Description and Formulation

The problem is a linear programming optimization problem. Tom's Florist wants to maximize profit by selling sunflowers and roses under certain constraints.

- Profit per bouquet of sunflowers: $7
- Profit per bouquet of roses: $12
- Time required for sunflowers:
  - Clipping: 4 minutes
  - Packaging: 3 minutes
- Time required for roses:
  - Clipping: 5 minutes
  - Packaging: 7 minutes
- Total available time:
  - Clipping: 1200 minutes
  - Packaging: 800 minutes
- Minimum bouquets of sunflowers to be sold: 30

## Decision Variables

Let \(S\) be the number of bouquets of sunflowers and \(R\) be the number of bouquets of roses.

## Objective Function

The objective is to maximize profit:
\[ \text{Maximize:} \quad 7S + 12R \]

## Constraints

1. Clipping time constraint:
\[ 4S + 5R \leq 1200 \]
2. Packaging time constraint:
\[ 3S + 7R \leq 800 \]
3. Minimum sunflowers constraint:
\[ S \geq 30 \]
4. Non-negativity constraints:
\[ S \geq 0, R \geq 0 \]
Since \(S\) and \(R\) represent the number of bouquets, they must be integers. However, for the LP formulation, we'll first consider them as continuous variables and then round if necessary.

## Gurobi Code

```python
import gurobi

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

    # Define variables
    S = model.addVar(lb=0, name="Sunflowers")
    R = model.addVar(lb=0, name="Roses")

    # Objective function: Maximize profit
    model.setObjective(7 * S + 12 * R, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(4 * S + 5 * R <= 1200, name="Clipping_Time")
    model.addConstr(3 * S + 7 * R <= 800, name="Packaging_Time")
    model.addConstr(S >= 30, name="Min_Sunflowers")

    # Solve the model
    model.optimize()

    # Check if the model is optimized
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal Solution: Sunflowers = {S.varValue}, Roses = {R.varValue}")
        print(f"Max Profit: ${model.objVal:.2f}")
    else:
        print("The model is infeasible.")

solve_florist_problem()
```

This code defines the optimization problem using Gurobi's Python interface, solves it, and prints out the optimal solution if one exists. Note that the solution values for \(S\) and \(R\) are accessed via `varValue` attribute of the variable objects, and the optimal objective value is accessed via `objVal` attribute of the model. If the problem is infeasible, it prints a corresponding message.