## Step 1: Define the symbolic variables
Let's define the symbolic variables for the problem:
- $x_1$ represents the number of youth doses.
- $x_2$ represents the number of adult doses.

## Step 2: Translate the objective function into symbolic notation
The objective is to maximize profit. Youth doses are sold for a profit of $5, and adult doses are sold for a profit of $3. Therefore, the objective function can be represented as:
\[ \text{Maximize:} \quad 5x_1 + 3x_2 \]

## 3: Translate the constraints into symbolic notation
1. There is only 5000 grams of extract available. Youth doses contain 20 grams, and adult doses contain 35 grams:
\[ 20x_1 + 35x_2 \leq 5000 \]
2. At least three times as many youth doses are needed than adult doses:
\[ x_1 \geq 3x_2 \]
3. A minimum of 10 adult doses need to be made:
\[ x_2 \geq 10 \]
4. Non-negativity constraints (number of doses cannot be negative):
\[ x_1 \geq 0, \quad x_2 \geq 0 \]

## 4: Provide the symbolic representation of the problem
```json
{
'sym_variables': [('x1', 'youth doses'), ('x2', 'adult doses')],
'objective_function': '5*x1 + 3*x2',
'constraints': [
    '20*x1 + 35*x2 <= 5000',
    'x1 >= 3*x2',
    'x2 >= 10',
    'x1 >= 0',
    'x2 >= 0'
]
}
```

## 5: Convert the problem into Gurobi code
```python
import gurobi

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

    # Define the variables
    x1 = model.addVar(lb=0, name="youth_doses")
    x2 = model.addVar(lb=10, name="adult_doses")

    # Objective function: Maximize 5*x1 + 3*x2
    model.setObjective(5*x1 + 3*x2, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(20*x1 + 35*x2 <= 5000, name="extract_constraint")
    model.addConstr(x1 >= 3*x2, name="demand_constraint")

    # Solve the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: x1 = {x1.varValue}, x2 = {x2.varValue}")
    else:
        print("The model is infeasible")

solve_optimization_problem()
```