```json
{
  "sym_variables": [
    ("x1", "touchscreen phone"),
    ("x2", "flip phone")
  ],
  "objective_function": "150*x1 + 200*x2",
  "constraints": [
    "30*x1 + 80*x2 <= 5000",
    "20*x1 + 15*x2 <= 3750",
    "x1 >= 0",
    "x2 >= 0"
  ]
}
```

```python
from gurobipy import Model, GRB

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

# Create variables
touchscreen = m.addVar(vtype=GRB.CONTINUOUS, name="touchscreen")
flip = m.addVar(vtype=GRB.CONTINUOUS, name="flip")

# Set objective function
m.setObjective(150 * touchscreen + 200 * flip, GRB.MAXIMIZE)

# Add constraints
m.addConstr(30 * touchscreen + 80 * flip <= 5000, "hardware_setup")
m.addConstr(20 * touchscreen + 15 * flip <= 3750, "software_verification")
m.addConstr(touchscreen >= 0, "touchscreen_nonnegative")  # Ensure non-negative production
m.addConstr(flip >= 0, "flip_nonnegative")  # Ensure non-negative production


# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print(f"Optimal profit: ${m.objVal:.2f}")
    print(f"Touchscreen phones to produce: {touchscreen.x:.2f}")
    print(f"Flip phones to produce: {flip.x:.2f}")
elif m.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {m.status}")

```
