Here's the Gurobi code to solve your optimization problem:

```python
from gurobipy import Model, GRB

# Create a new model
model = Model("food_optimization")

# Create variables
chicken_drumsticks = model.addVar(lb=0, name="chicken_drumsticks")
cheeseburgers = model.addVar(lb=0, name="cheeseburgers")
bananas = model.addVar(lb=0, vtype=GRB.INTEGER, name="bananas")
bowls_of_pasta = model.addVar(lb=0, vtype=GRB.INTEGER, name="bowls_of_pasta")
milkshakes = model.addVar(lb=0, name="milkshakes")

# Set objective function
model.setObjective(2.43 * chicken_drumsticks + 5.03 * cheeseburgers + 8.18 * bananas + 8.68 * bowls_of_pasta + 2.76 * milkshakes, GRB.MAXIMIZE)

# Add constraints
model.addConstr(5.56 * chicken_drumsticks + 1.43 * cheeseburgers + 2.3 * bananas + 5.72 * bowls_of_pasta + 5.41 * milkshakes <= 116, "c0") # umami index
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta + 4.58 * milkshakes <= 163, "c1") # iron
model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.98 * bananas + 0.83 * bowls_of_pasta + 5.0 * milkshakes <= 155, "c2") # sourness index

model.addConstr(3.93 * bananas + 4.58 * milkshakes >= 20, "c3")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers >= 14, "c4")
model.addConstr(0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta >= 31, "c5")
model.addConstr(5.58 * chicken_drumsticks + 3.93 * bananas + 4.58 * milkshakes >= 31, "c6")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 4.58 * milkshakes >= 31, "c7")
model.addConstr(0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta >= 20, "c8")
model.addConstr(5.58 * chicken_drumsticks + 3.93 * bananas + 4.58 * milkshakes >= 20, "c9")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 4.58 * milkshakes >= 20, "c10")
model.addConstr(0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta >= 17, "c11")
model.addConstr(5.58 * chicken_drumsticks + 3.93 * bananas + 4.58 * milkshakes >= 17, "c12")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 4.58 * milkshakes >= 17, "c13")


for sourness_val in [22, 23, 24, 28, 30]:
    model.addConstr(3.82 * chicken_drumsticks + 0.98 * bananas + 0.83 * bowls_of_pasta >= sourness_val, f"c14_{sourness_val}")
    model.addConstr(3.97 * cheeseburgers + 0.98 * bananas + 0.83 * bowls_of_pasta >= sourness_val, f"c15_{sourness_val}")
    model.addConstr(3.97 * cheeseburgers + 0.98 * bananas + 5.0 * milkshakes >= sourness_val, f"c16_{sourness_val}")
    model.addConstr(3.82 * chicken_drumsticks + 0.98 * bananas + 5.0 * milkshakes >= sourness_val, f"c17_{sourness_val}")
    model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.83 * bowls_of_pasta >= sourness_val, f"c18_{sourness_val}")
    model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.98 * bananas >= sourness_val, f"c19_{sourness_val}")
    model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 5.0 * milkshakes >= sourness_val, f"c20_{sourness_val}")


model.addConstr(2.3 * bananas + 5.41 * milkshakes <= 27, "c21")
model.addConstr(2.3 * bananas + 5.72 * bowls_of_pasta <= 51, "c22")
model.addConstr(1.43 * cheeseburgers + 5.72 * bowls_of_pasta <= 114, "c23")
model.addConstr(5.72 * bowls_of_pasta + 5.41 * milkshakes <= 49, "c24")
model.addConstr(1.43 * cheeseburgers + 2.3 * bananas <= 65, "c25")
model.addConstr(5.56 * chicken_drumsticks + 1.43 * cheeseburgers <= 99, "c26")
model.addConstr(5.56 * chicken_drumsticks + 1.43 * cheeseburgers + 2.3 * bananas + 5.72 * bowls_of_pasta + 5.41 * milkshakes <= 99, "c27")

model.addConstr(0.65 * cheeseburgers + 2.1 * bowls_of_pasta <= 147, "c28")
model.addConstr(5.58 * chicken_drumsticks + 2.1 * bowls_of_pasta <= 45, "c29")
model.addConstr(0.65 * cheeseburgers + 4.58 * milkshakes <= 102, "c30")
model.addConstr(5.58 * chicken_drumsticks + 4.58 * milkshakes <= 85, "c31")
model.addConstr(3.93 * bananas + 4.58 * milkshakes <= 41, "c32")
model.addConstr(0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta <= 157, "c33")
model.addConstr(0.65 * cheeseburgers + 2.1 * bowls_of_pasta + 4.58 * milkshakes <= 134, "c34")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 2.1 * bowls_of_pasta <= 61, "c35")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 4.58 * milkshakes <= 60, "c36")
model.addConstr(3.93 * bananas + 2.1 * bowls_of_pasta + 4.58 * milkshakes <= 145, "c37")
model.addConstr(5.58 * chicken_drumsticks + 3.93 * bananas + 2.1 * bowls_of_pasta <= 76, "c38")
model.addConstr(5.58 * chicken_drumsticks + 2.1 * bowls_of_pasta + 4.58 * milkshakes <= 49, "c39")
model.addConstr(0.65 * cheeseburgers + 3.93 * bananas + 4.58 * milkshakes <= 41, "c40")
model.addConstr(5.58 * chicken_drumsticks + 0.65 * cheeseburgers + 3.93 * bananas + 2.1 * bowls_of_pasta + 4.58 * milkshakes <= 41, "c41")


model.addConstr(3.97 * cheeseburgers + 0.83 * bowls_of_pasta <= 68, "c42")
model.addConstr(0.98 * bananas + 0.83 * bowls_of_pasta <= 133, "c43")
model.addConstr(3.82 * chicken_drumsticks + 5.0 * milkshakes <= 50, "c44")
model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.98 * bananas <= 150, "c45")
model.addConstr(0.98 * bananas + 0.83 * bowls_of_pasta + 5.0 * milkshakes <= 99, "c46")
model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.83 * bowls_of_pasta <= 55, "c47")
model.addConstr(3.82 * chicken_drumsticks + 0.98 * bananas + 5.0 * milkshakes <= 104, "c48")
model.addConstr(3.97 * cheeseburgers + 0.83 * bowls_of_pasta + 5.0 * milkshakes <= 57, "c49")
model.addConstr(3.82 * chicken_drumsticks + 3.97 * cheeseburgers + 0.98 * bananas + 0.83 * bowls_of_pasta + 5.0 * milkshakes <= 57, "c50")


# Optimize model
model.optimize()

# Print results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for v in model.getVars():
        print(f"{v.varName}: {v.x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization ended with status: {model.status}")

```
