## Problem Description and Formulation

The problem is to determine the number of units of two digital piano models, Piano A and Piano B, that TomMusic should stock daily to attract at least 250 customers into its store while minimizing the cost of the sales campaign. The campaign has a maximum daily budget of $450.

## Decision Variables

Let \(x\) be the number of units of Piano A and \(y\) be the number of units of Piano B.

## Objective Function

The objective is to minimize the total cost of the sales campaign. The cost for each unit of Piano A is $20 (acquisition) + $12 (sales and maintenance) = $32, and for each unit of Piano B, it is $15 (acquisition) + $4 (sales and maintenance) = $19. Therefore, the objective function to minimize is \(32x + 19y\).

## Constraints

1. **Budget Constraint**: The total cost of acquiring the pianos should not exceed $450. Therefore, \(20x + 15y \leq 450\).
2. **Customer Attraction Constraint**: The total number of customers attracted should be at least 250. Given that Piano A attracts 25 customers and Piano B attracts 10 customers per unit, we have \(25x + 10y \geq 250\).
3. **Non-Negativity Constraint**: The number of units of each piano model should be non-negative, i.e., \(x \geq 0\) and \(y \geq 0\).

## Gurobi Code

```python
import gurobi

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

    # Define the decision variables
    x = model.addVar(lb=0, vtype=gurobi.GRB.CONTINUOUS, name="Piano_A")
    y = model.addVar(lb=0, vtype=gurobi.GRB.CONTINUOUS, name="Piano_B")

    # Objective function: Minimize the total cost
    model.setObjective(32*x + 19*y, gurobi.GRB.MINIMIZE)

    # Budget constraint
    model.addConstr(20*x + 15*y <= 450, name="Budget_Constraint")

    # Customer attraction constraint
    model.addConstr(25*x + 10*y >= 250, name="Customer_Constraint")

    # Solve the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution found: x = {x.varValue}, y = {y.varValue}")
        print(f"Minimum cost: {model.objVal}")
    else:
        print("No optimal solution found")

solve_piano_problem()
```

This code defines the optimization problem using Gurobi's Python interface, solves it, and prints out the optimal values of \(x\) and \(y\) (the number of units of Piano A and Piano B to stock) and the minimum cost of the campaign. If no optimal solution is found (for example, if the problem is infeasible), it will indicate that as well.