To solve this problem, we first need to define the variables and the objective function. Let's denote the number of t-shirts as \(t\) and the number of sweaters as \(s\). The objective is to maximize profit, which is calculated as the total revenue from selling t-shirts and sweaters minus their costs.

The cost of buying \(t\) t-shirts is $20\(t\) and the cost of buying \(s\) sweaters is $30\(s\). The total budget is $1000, so we have:
\[20t + 30s \leq 1000\]

Each t-shirt is sold for a profit of $15, and each sweater for a profit of $20. Thus, the total profit from selling \(t\) t-shirts and \(s\) sweaters is:
\[15t + 20s\]

The constraints given are:
1. At least 20 but at most 40 t-shirts are sold: \(20 \leq t \leq 40\)
2. The number of sweaters sold is at most half the number of t-shirts sold: \(s \leq \frac{1}{2}t\)

Now, let's translate these conditions into Gurobi code in Python:

```python
from gurobipy import *

# Create a model
m = Model("T-Shirts_and_Sweaters")

# Define variables
t = m.addVar(lb=20, ub=40, vtype=GRB.INTEGER, name="t-shirts")
s = m.addVar(lb=0, ub=20, vtype=GRB.INTEGER, name="sweaters")

# Add constraints
m.addConstr(20*t + 30*s <= 1000, "budget_constraint")
m.addConstr(s <= 0.5*t, "sweater_limit")

# Set objective function to maximize profit
m.setObjective(15*t + 20*s, GRB.MAXIMIZE)

# Optimize the model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: Buy {t.x} t-shirts and {s.x} sweaters.")
    print(f"Maximum profit: ${15*t.x + 20*s.x}")
else:
    print("No optimal solution found")
```