```json
{
  "sym_variables": [
    ("x1", "protein drink servings"),
    ("x2", "fruit snack servings")
  ],
  "objective_function": "4*x1 + 12*x2",
  "constraints": [
    "45*x1 + 400*x2 >= 100",
    "200*x1 + 600*x2 >= 500",
    "300*x1 + 200*x2 >= 3000",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

```python
import gurobipy as gp

# Create a new model
m = gp.Model("Mary's Diet")

# Create variables
protein_drink = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="protein_drink")
fruit_snack = m.addVar(lb=0, vtype=gp.GRB.CONTINUOUS, name="fruit_snack")


# Set objective function
m.setObjective(4 * protein_drink + 12 * fruit_snack, gp.GRB.MINIMIZE)

# Add constraints
m.addConstr(45 * protein_drink + 400 * fruit_snack >= 100, "Vitamin A")
m.addConstr(200 * protein_drink + 600 * fruit_snack >= 500, "Vitamin C")
m.addConstr(300 * protein_drink + 200 * fruit_snack >= 3000, "Protein")


# Optimize model
m.optimize()

# Check if a solution was found
if m.status == gp.GRB.OPTIMAL:
    print(f"Optimal cost: ${m.objVal:.2f}")
    print(f"Protein drink servings: {protein_drink.x:.2f}")
    print(f"Fruit snack servings: {fruit_snack.x:.2f}")
elif m.status == gp.GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {m.status}")

```
