```json
{
  "sym_variables": [
    ("x1", "new grad engineers"),
    ("x2", "senior engineers")
  ],
  "objective_function": "1000*x1 + 3000*x2",
  "constraints": [
    "1000*x1 + 3000*x2 <= 100000",
    "x1 + x2 >= 50",
    "x2 >= 10",
    "x2 >= (1/3)*x1"
  ]
}
```

```python
import gurobipy as gp
from gurobipy import GRB

# Create a new model
m = gp.Model("minimize_wage_bill")

# Create variables
new_grads = m.addVar(lb=0, vtype=GRB.INTEGER, name="new_grads")  # Integer variable
senior_eng = m.addVar(lb=0, vtype=GRB.INTEGER, name="senior_eng") # Integer variable


# Set objective function
m.setObjective(1000 * new_grads + 3000 * senior_eng, GRB.MINIMIZE)

# Add constraints
m.addConstr(1000 * new_grads + 3000 * senior_eng <= 100000, "wage_bill")
m.addConstr(new_grads + senior_eng >= 50, "total_engineers")
m.addConstr(senior_eng >= 10, "min_senior_eng")
m.addConstr(senior_eng >= (1/3) * new_grads, "senior_eng_ratio")


# Optimize model
m.optimize()

# Print results
if m.status == GRB.OPTIMAL:
    print(f"Optimal wage bill: ${m.objVal}")
    print(f"Number of new grad engineers: {new_grads.x}")
    print(f"Number of senior engineers: {senior_eng.x}")
elif m.status == GRB.INFEASIBLE:
    print("The model is infeasible.")
else:
    print(f"Optimization ended with status {m.status}")

```
