## Problem Description and Formulation

The problem is a linear programming optimization problem. The goal is to maximize the profit of a makeup store by determining the optimal number of bottles of perfume and mascara to buy and sell.

### Decision Variables

* $x$: number of bottles of perfume to buy and sell
* $y$: number of bottles of mascara to buy and sell

### Objective Function

The profit from selling $x$ bottles of perfume is $20x$ and the profit from selling $y$ bottles of mascara is $15y$. The total profit is $20x + 15y$.

### Constraints

* Budget constraint: The store has a budget of $20,000. Each bottle of perfume costs $50 and each bottle of mascara costs $40. Therefore, the total cost is $50x + 40y \leq 20,000$.
* Perfume sales constraint: The owner estimates that at least 20 but at most 40 bottles of perfume will be sold. Therefore, $20 \leq x \leq 40$.
* Mascara sales constraint: The number of mascara sold is at most a third the number of perfume sold. Therefore, $y \leq \frac{1}{3}x$.

### Non-Negativity Constraints

* $x \geq 0$ and $y \geq 0$, since the number of bottles cannot be negative.

## Gurobi Code

```python
import gurobi

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

    # Define decision variables
    x = model.addVar(lb=0, ub=40, name="perfume")
    y = model.addVar(lb=0, name="mascara")

    # Set objective function
    model.setObjective(20 * x + 15 * y, gurobi.GRB.MAXIMIZE)

    # Add budget constraint
    model.addConstr(50 * x + 40 * y <= 20000, name="budget")

    # Add perfume sales constraint
    model.addConstr(x >= 20, name="perfume_min")
    model.addConstr(x <= 40, name="perfume_max")

    # Add mascara sales constraint
    model.addConstr(y <= x / 3, name="mascara_max")

    # Optimize the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print("Optimal solution found.")
        print(f"Number of bottles of perfume to buy and sell: {x.varValue}")
        print(f"Number of bottles of mascara to buy and sell: {y.varValue}")
        print(f"Maximum profit: {model.objVal}")
    else:
        print("No optimal solution found.")

solve_makeup_store_problem()
```