```json
{
  "sym_variables": [
    ("x1", "oval pots"),
    ("x2", "square pots")
  ],
  "objective_function": "4.5 * x1 + 8 * x2",
  "constraints": [
    "40 * x1 + 35 * x2 <= 2500",
    "50 * x1 + 80 * x2 <= 3800",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

```python
import gurobipy as gp

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

# Create variables
oval_pots = model.addVar(vtype=gp.GRB.CONTINUOUS, name="oval_pots")  # x1
square_pots = model.addVar(vtype=gp.GRB.CONTINUOUS, name="square_pots") # x2

# Set objective function
model.setObjective(4.5 * oval_pots + 8 * square_pots, gp.GRB.MAXIMIZE)

# Add constraints
model.addConstr(40 * oval_pots + 35 * square_pots <= 2500, "shaping_time")
model.addConstr(50 * oval_pots + 80 * square_pots <= 3800, "baking_time")
model.addConstr(oval_pots >= 0, "oval_pots_nonnegative")
model.addConstr(square_pots >= 0, "square_pots_nonnegative")


# Optimize model
model.optimize()

# Print results
if model.status == gp.GRB.OPTIMAL:
    print(f"Optimal profit: ${model.objVal:.2f}")
    print(f"Oval pots: {oval_pots.x:.2f}")
    print(f"Square pots: {square_pots.x:.2f}")
elif model.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {model.status}")

```
