## Problem Description and Formulation

The problem is a classic example of a linear programming problem. The cafe wants to maximize its profit by producing the optimal number of lattes and cappuccinos given the available resources (milk and coffee).

Let's define the decision variables:

* $L$ = number of lattes produced
* $C$ = number of cappuccinos produced

The objective function is to maximize the profit:

* Profit per latte = $2
* Profit per cappuccino = $1
* Total profit = $2L + $1C

The constraints are:

* Milk constraint: 4 units of milk per latte + 2 units of milk per cappuccino ≤ 80 units of milk available
* Coffee constraint: 1 unit of coffee per latte + 2 units of coffee per cappuccino ≤ 50 units of coffee available
* Non-negativity constraint: $L ≥ 0, C ≥ 0$ (cannot produce a negative number of lattes or cappuccinos)

## Mathematical Formulation

Maximize: 2L + C

Subject to:

* 4L + 2C ≤ 80 (milk constraint)
* L + 2C ≤ 50 (coffee constraint)
* L ≥ 0, C ≥ 0 (non-negativity constraint)

## Gurobi Code

```python
import gurobi

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

    # Define the decision variables
    L = model.addVar(lb=0, name="Lattes")
    C = model.addVar(lb=0, name="Cappuccinos")

    # Define the objective function
    model.setObjective(2*L + C, gurobi.GRB.MAXIMIZE)

    # Define the milk constraint
    model.addConstr(4*L + 2*C <= 80, name="Milk_Constraint")

    # Define the coffee constraint
    model.addConstr(L + 2*C <= 50, name="Coffee_Constraint")

    # Optimize the model
    model.optimize()

    # Print the solution
    if model.status == gurobi.GRB.OPTIMAL:
        print(f"Optimal solution: Lattes = {L.varValue}, Cappuccinos = {C.varValue}")
        print(f"Maximum profit: ${2*L.varValue + C.varValue:.2f}")
    else:
        print("No optimal solution found")

solve_cafe_problem()
```