To solve John's cereal mixing problem, we first need to define the variables and constraints involved. Let's denote the number of servings of cereal A as \(x_A\) and the number of servings of cereal B as \(x_B\).

The objective is to minimize the total cost of cereals A and B, which can be represented by the function:
\[ \text{Minimize} \quad 0.45x_A + 0.55x_B \]

We have two main constraints based on the nutritional requirements:
1. **Iron Requirement**: At least 400 units of iron are needed.
   - Each serving of cereal A provides 25 units of iron, and each serving of cereal B provides 20 units of iron.
   - Therefore, the constraint can be written as: \(25x_A + 20x_B \geq 400\).

2. **Fiber Requirement**: At least 450 units of fiber are needed.
   - Each serving of cereal A provides 30 units of fiber, and each serving of cereal B provides 40 units of fiber.
   - Therefore, the constraint can be written as: \(30x_A + 40x_B \geq 450\).

Additionally, we have non-negativity constraints since John cannot buy a negative number of servings:
- \(x_A \geq 0\)
- \(x_B \geq 0\)

Now, let's translate these constraints and the objective function into Gurobi code in Python:

```python
from gurobipy import *

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

# Define variables
x_A = m.addVar(name="cereal_A", vtype=GRB.CONTINUOUS, lb=0)
x_B = m.addVar(name="cereal_B", vtype=GRB.CONTINUOUS, lb=0)

# Set the objective function
m.setObjective(0.45*x_A + 0.55*x_B, GRB.MINIMIZE)

# Add constraints
m.addConstr(25*x_A + 20*x_B >= 400, name="iron_requirement")
m.addConstr(30*x_A + 40*x_B >= 450, name="fiber_requirement")

# Optimize the model
m.optimize()

# Print the results
if m.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    print(f"Servings of Cereal A: {x_A.x}")
    print(f"Servings of Cereal B: {x_B.x}")
    print(f"Total Cost: ${m.objVal:.2f}")
else:
    print("No optimal solution found")
```