## Problem Description and Formulation

The vendor's goal is to maximize profit by selling coffees and hot chocolates at an ice hockey game, subject to certain constraints. Let's define the decision variables and the objective function:

- **Decision Variables:**
  - \(x\): Number of coffees to sell
  - \(y\): Number of hot chocolates to sell

- **Objective Function:**
  - Maximize profit \(P = 0.22x + 0.14y\)

- **Constraints:**
  1. \(x \geq 40\) (at least 40 coffees)
  2. \(y \geq 20\) (at least 20 hot chocolates)
  3. \(x \leq 60\) (no more than 60 coffees)
  4. \(y \leq 35\) (no more than 35 hot chocolates)
  5. \(x + y \leq 75\) (no more than 75 items total)
  6. \(x, y \geq 0\) and are integers (non-negativity and integrality constraints)

However, since Gurobi can handle continuous variables and we are not explicitly told the items must be sold in whole numbers (though implicitly they should be), we will proceed with the assumption that \(x\) and \(y\) can be continuous for now. If integer solutions are required, we can adjust the model accordingly.

## Gurobi Code

```python
import gurobi

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

    # Define variables
    x = model.addVar(lb=0, ub=60, name="coffees")
    y = model.addVar(lb=0, ub=35, name="hot_chocolates")

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

    # Constraints
    model.addConstr(x >= 40, name="min_coffees")
    model.addConstr(y >= 20, name="min_hot_chocolates")
    model.addConstr(x <= 60, name="max_coffees")
    model.addConstr(y <= 35, name="max_hot_chocolates")
    model.addConstr(x + y <= 75, name="total_items")

    # Update model
    model.update()

    # Solve
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal profit: {model.objVal}")
        print(f"Coffees to sell: {x.varValue}")
        print(f"Hot chocolates to sell: {y.varValue}")
    else:
        print("No optimal solution found")

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

To ensure an integer solution (as implied by the context of selling items), you can add the `vtype` parameter when creating variables:

```python
x = model.addVar(lb=40, ub=60, vtype=gurobi.GRB.INTEGER, name="coffees")
y = model.addVar(lb=20, ub=35, vtype=gurobi.GRB.INTEGER, name="hot_chocolates")
```

And adjust the bounds to reflect the minimum requirements directly:

This adjustment will ensure that the solution respects the integer requirement for the number of items to sell. 

Let's adjust and enclose the final code:

```python
import gurobi

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

    # Define variables with integer requirement
    x = model.addVar(lb=40, ub=60, vtype=gurobi.GRB.INTEGER, name="coffees")
    y = model.addVar(lb=20, ub=35, vtype=gurobi.GRB.INTEGER, name="hot_chocolates")

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

    # Constraints
    model.addConstr(x + y <= 75, name="total_items")

    # Update model
    model.update()

    # Solve
    model.optimize()

    # Print solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal profit: {model.objVal}")
        print(f"Coffees to sell: {x.varValue}")
        print(f"Hot chocolates to sell: {y.varValue}")
    else:
        print("No optimal solution found")

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