To solve the given optimization problem, we first need to translate the natural language description into a symbolic representation. This involves defining variables for the quantities of peanut butter and almond butter smoothies, formulating the objective function that represents the total profit, and listing the constraints based on the availability of almond milk and protein powder.

Let's define:
- $x_1$ as the number of peanut butter smoothies,
- $x_2$ as the number of almond butter smoothies.

The objective function, which is to maximize the total profit, can be written as:
\[5x_1 + 4x_2\]

Given that each peanut butter smoothie requires 3 units of almond milk and each almond butter smoothie requires 2 units, and there are 50 units of almond milk available, we have the constraint:
\[3x_1 + 2x_2 \leq 50\]

For protein powder, with each peanut butter smoothie requiring 1 unit and each almond butter smoothie requiring 1.5 units, and 40 units available, the constraint is:
\[x_1 + 1.5x_2 \leq 40\]

Additionally, since we cannot make a negative number of smoothies, we have non-negativity constraints:
\[x_1 \geq 0\]
\[x_2 \geq 0\]

Thus, the symbolic representation of our problem is:

```json
{
    'sym_variables': [('x1', 'peanut butter smoothies'), ('x2', 'almond butter smoothies')], 
    'objective_function': '5*x1 + 4*x2', 
    'constraints': ['3*x1 + 2*x2 <= 50', 'x1 + 1.5*x2 <= 40', 'x1 >= 0', 'x2 >= 0']
}
```

To solve this problem using Gurobi in Python, we will use the following code:

```python
from gurobipy import *

# Create a new model
m = Model("Smoothie_Optimization")

# Define variables
x1 = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="peanut_butter_smoothies")
x2 = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="almond_butter_smoothies")

# Set the objective function
m.setObjective(5*x1 + 4*x2, GRB.MAXIMIZE)

# Add constraints
m.addConstr(3*x1 + 2*x2 <= 50, "almond_milk_constraint")
m.addConstr(x1 + 1.5*x2 <= 40, "protein_powder_constraint")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found.")
    print(f"Number of peanut butter smoothies: {x1.x}")
    print(f"Number of almond butter smoothies: {x2.x}")
    print(f"Maximum profit: ${m.objVal:.2f}")
else:
    print("No optimal solution found.")
```