Here's the formulation of the problem and the Gurobi code to solve it:

**Decision Variables:**

* `x`: Number of t-shirts to buy and sell
* `y`: Number of sweaters to buy and sell

**Objective Function:**

Maximize profit: `15x + 20y`

**Constraints:**

* Budget constraint: `20x + 30y <= 1000`
* Minimum t-shirt sales: `x >= 20`
* Maximum t-shirt sales: `x <= 40`
* Sweater sales limit: `y <= 0.5x`
* Non-negativity: `x, y >= 0`
* Integer constraint: `x, y` must be integers (since you can't buy/sell fractions of shirts/sweaters)


```python
import gurobipy as gp

# Create a new model
m = gp.Model("tshirt_sweater_optimization")

# Create variables
x = m.addVar(vtype=gp.GRB.INTEGER, name="t_shirts")
y = m.addVar(vtype=gp.GRB.INTEGER, name="sweaters")

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

# Add constraints
m.addConstr(20*x + 30*y <= 1000, "budget")
m.addConstr(x >= 20, "min_tshirts")
m.addConstr(x <= 40, "max_tshirts")
m.addConstr(y <= 0.5*x, "sweater_limit")

# Optimize model
m.optimize()

# Print results
if m.status == gp.GRB.OPTIMAL:
    print(f"Optimal Solution Found:")
    print(f"Number of T-shirts to buy/sell (x): {x.x}")
    print(f"Number of Sweaters to buy/sell (y): {y.x}")
    print(f"Maximum Profit: ${m.objVal}")
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization terminated with status {m.status}")

```
