To solve George's problem, we need to convert the natural language description into a symbolic representation of an optimization problem. Let's denote the number of sneakers as $x_1$ and the number of boots as $x_2$. The objective is to maximize the profit.

The profit per sneaker sold is $50, and the profit per boot sold is $80. Therefore, the total profit can be represented by the objective function: $50x_1 + 80x_2$.

There are two main constraints:
1. The monthly demand for these shoes (both sneakers and boots) is at most 50. This can be represented as: $x_1 + x_2 \leq 50$.
2. George does not want to spend more than $8750 buying these shoes, with each sneaker costing $150 and each boot costing $200. This constraint can be represented as: $150x_1 + 200x_2 \leq 8750$.

Additionally, since we cannot buy a negative number of items, we have the non-negativity constraints:
- $x_1 \geq 0$
- $x_2 \geq 0$

Thus, the symbolic representation of the problem is:

```json
{
    'sym_variables': [('x1', 'number of sneakers'), ('x2', 'number of boots')],
    'objective_function': '50*x1 + 80*x2',
    'constraints': ['x1 + x2 <= 50', '150*x1 + 200*x2 <= 8750', 'x1 >= 0', 'x2 >= 0']
}
```

Now, let's write the Gurobi code in Python to solve this linear programming problem:

```python
from gurobipy import *

# Create a new model
model = Model("George_Shoes_Problem")

# Add variables
x1 = model.addVar(vtype=GRB.CONTINUOUS, name="sneakers", lb=0)
x2 = model.addVar(vtype=GRB.CONTINUOUS, name="boots", lb=0)

# Set the objective function
model.setObjective(50*x1 + 80*x2, GRB.MAXIMIZE)

# Add constraints
model.addConstr(x1 + x2 <= 50, "demand_limit")
model.addConstr(150*x1 + 200*x2 <= 8750, "budget_limit")

# Optimize the model
model.optimize()

# Print the results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Number of sneakers: {x1.x}")
    print(f"Number of boots: {x2.x}")
    print(f"Total profit: ${50*x1.x + 80*x2.x:.2f}")
else:
    print("No optimal solution found")
```