## Problem Description and Formulation

The problem requires finding the optimal number of bottles of French perfume and Spanish perfume that Angela should buy to minimize costs while meeting the requirements for flower scent and fruit scent.

Let's define the decision variables:
- $x$: Number of bottles of French perfume
- $y$: Number of bottles of Spanish perfume

The objective is to minimize the total cost:
\[ \text{Minimize:} \quad 50x + 45y \]

Subject to the constraints:
1. Flower scent requirement: $20x + 30y \geq 150$
2. Fruit scent requirement: $50x + 40y \geq 60$
3. Non-negativity constraints: $x \geq 0, y \geq 0$

## Gurobi Code

```python
import gurobi

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

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

    # Objective function: Minimize cost
    model.setObjective(50*x + 45*y, sense=gurobi.GRB.MINIMIZE)

    # Constraints
    model.addConstr(20*x + 30*y >= 150, name="flower_scent_req")
    model.addConstr(50*x + 40*y >= 60, name="fruit_scent_req")

    # Optimize the model
    model.optimize()

    # Print the results
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution found. Cost: ${model.objval:.2f}")
        print(f"French perfume: {x.varValue:.2f} bottles")
        print(f"Spanish perfume: {y.varValue:.2f} bottles")
    else:
        print("No optimal solution found.")

# Run the function
solve_perfume_problem()
```

This code defines the optimization problem using Gurobi's Python interface, solves it, and prints out the optimal solution if one is found. Note that the decision variables are defined as continuous, which might not be suitable for all practical scenarios (as you cannot buy fractions of a bottle). If you need integer solutions, you should change `vtype=gurobi.GRB.CONTINUOUS` to `vtype=gurobi.GRB.INTEGER` for both `x` and `y`.