To solve John's problem, we need to maximize his profit by determining the optimal number of oval and square pots he should make each week. The decision variables are the number of oval pots (x) and the number of square pots (y). The objective function is to maximize profit, which can be calculated as 4.5x + 8y.

The constraints on John's production are based on the time available for shaping and baking. Each oval pot requires 40 minutes of shaping and 50 minutes of baking, while each square pot requires 35 minutes of shaping and 80 minutes of baking. The total shaping time available per week is 2500 minutes, and the total baking time available per week is 3800 minutes.

Therefore, we can set up the following constraints:

- Shaping time constraint: 40x + 35y ≤ 2500
- Baking time constraint: 50x + 80y ≤ 3800
- Non-negativity constraints: x ≥ 0 and y ≥ 0 (since John cannot make a negative number of pots)

Here is the Gurobi code to solve this linear programming optimization problem:

```python
from gurobipy import *

# Create a model
m = Model("Terracotta_Pots")

# Define decision variables
x = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Oval_Pots")
y = m.addVar(lb=0, vtype=GRB.CONTINUOUS, name="Square_Pots")

# Set the objective function (maximize profit)
m.setObjective(4.5*x + 8*y, GRB.MAXIMIZE)

# Add constraints
m.addConstr(40*x + 35*y <= 2500, "Shaping_Time")
m.addConstr(50*x + 80*y <= 3800, "Baking_Time")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print(f"Optimal number of oval pots: {x.x:.2f}")
    print(f"Optimal number of square pots: {y.x:.2f}")
    print(f"Maximum profit: ${m.objVal:.2f}")
else:
    print("The model is infeasible")
```