## Problem Description and Formulation

The problem is a classic example of a linear programming problem. John, the artisan, wants to maximize his profit by producing oval and square pots under certain constraints. The constraints are:

- Shaping time: 2500 minutes per week
- Baking time: 3800 minutes per week
- Profit per oval pot: $4.5
- Profit per square pot: $8
- Time requirements:
  - Oval pot: 40 minutes shaping, 50 minutes baking
  - Square pot: 35 minutes shaping, 80 minutes baking

Let's denote:
- \(x\) as the number of oval pots
- \(y\) as the number of square pots

The objective function to maximize profit is:
\[ \text{Maximize:} \quad 4.5x + 8y \]

Subject to:
\[ 40x + 35y \leq 2500 \] (Shaping time constraint)
\[ 50x + 80y \leq 3800 \] (Baking time constraint)
\[ x \geq 0, y \geq 0 \] (Non-negativity constraints, as the number of pots cannot be negative)

## Gurobi Code

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

```python
import gurobi

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

    # Define variables
    x = model.addVar(name="oval_pots", lb=0, vtype=gurobi.GRB.CONTINUOUS)
    y = model.addVar(name="square_pots", lb=0, vtype=gurobi.GRB.CONTINUOUS)

    # Objective function: Maximize profit
    model.setObjective(4.5 * x + 8 * y, gurobi.GRB.MAXIMIZE)

    # Constraints
    model.addConstr(40 * x + 35 * y <= 2500, name="shaping_time_constraint")
    model.addConstr(50 * x + 80 * y <= 3800, name="baking_time_constraint")

    # Optimize
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution found. Oval pots: {x.varValue}, Square pots: {y.varValue}")
        print(f"Maximum profit: {model.objVal}")
    else:
        print("No optimal solution found.")

if __name__ == "__main__":
    solve_optimization_problem()
```

However, note that Gurobi typically requires a license for commercial use and can be used for free for academic purposes. Also, ensure you have the Gurobi Python package installed (`gurobipy`). 

The code defines a model, sets up the variables and constraints according to the problem description, and then solves the optimization problem. If an optimal solution is found, it prints out the number of each type of pot to produce and the maximum achievable profit.