```python
from gurobipy import Model, GRB, quicksum

# Define the model
model = Model("Food Optimization")

# Define the variables
foods = ['granola bars', 'hamburgers', 'potatoes', 'black beans', 'eggs']
x = model.addVars(foods, name=foods)

# Set variable types
x['granola bars'].vtype = GRB.CONTINUOUS
x['hamburgers'].vtype = GRB.INTEGER
x['potatoes'].vtype = GRB.INTEGER
x['black beans'].vtype = GRB.CONTINUOUS
x['eggs'].vtype = GRB.CONTINUOUS


# Define the objective function
model.setObjective(2 * x['granola bars'] + 6 * x['hamburgers'] + 8 * x['potatoes'] + 7 * x['black beans'] + 5 * x['eggs'], GRB.MAXIMIZE)

# Define the resource constraints
resources = {
    'r0': {'description': 'milligrams of iron', 'upper_bound': 239, 'values': [5, 9, 20, 4, 24]},
    'r1': {'description': 'sourness index', 'upper_bound': 231, 'values': [26, 26, 8, 8, 3]}
}

for resource, data in resources.items():
    model.addConstr(quicksum(data['values'][i] * x[foods[i]] for i in range(len(foods))) <= data['upper_bound'], name=resource)

# Define the additional constraints
model.addConstr(5 * x['granola bars'] + 24 * x['eggs'] >= 35)
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] >= 32)
model.addConstr(9 * x['hamburgers'] + 20 * x['potatoes'] >= 43)
model.addConstr(20 * x['potatoes'] + 24 * x['eggs'] >= 38)
model.addConstr(9 * x['hamburgers'] + 24 * x['eggs'] >= 34)
model.addConstr(5 * x['granola bars'] + 4 * x['black beans'] >= 33)
model.addConstr(4 * x['black beans'] + 24 * x['eggs'] >= 15)
model.addConstr(9 * x['hamburgers'] + 4 * x['black beans'] >= 34)
model.addConstr(20 * x['potatoes'] + 4 * x['black beans'] + 24 * x['eggs'] >= 36)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 20 * x['potatoes'] >= 36)
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] + 24 * x['eggs'] >= 36)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 24 * x['eggs'] >= 36)
model.addConstr(20 * x['potatoes'] + 4 * x['black beans'] + 24 * x['eggs'] >= 32)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 20 * x['potatoes'] >= 32)
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] + 24 * x['eggs'] >= 32)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 24 * x['eggs'] >= 32)
model.addConstr(20 * x['potatoes'] + 4 * x['black beans'] + 24 * x['eggs'] >= 26)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 20 * x['potatoes'] >= 26)
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] + 24 * x['eggs'] >= 26)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 24 * x['eggs'] >= 26)
model.addConstr(20 * x['potatoes'] + 4 * x['black beans'] + 24 * x['eggs'] >= 37)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 20 * x['potatoes'] >= 37)
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] + 24 * x['eggs'] >= 37)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 24 * x['eggs'] >= 37)


#Sourness index constraints (simplified and deduplicated)
model.addConstr(8 * x['potatoes'] + 8 * x['black beans'] + 3 * x['eggs'] >= 46)
model.addConstr(26 * x['granola bars'] + 26 * x['hamburgers'] + 3 * x['eggs'] >= 46)
model.addConstr(26 * x['granola bars'] + 26 * x['hamburgers'] + 8 * x['black beans'] >= 46)
model.addConstr(26 * x['hamburgers'] + 8 * x['potatoes'] + 8 * x['black beans'] >= 46)
model.addConstr(26 * x['granola bars'] + 8 * x['potatoes'] + 3 * x['eggs'] >= 46)
model.addConstr(26 * x['hamburgers'] + 8 * x['black beans'] + 3 * x['eggs'] >= 46)
model.addConstr(26 * x['granola bars'] + 8 * x['black beans'] + 3 * x['eggs'] >= 46)
model.addConstr(7 * x['granola bars'] - 10 * x['eggs'] >= 0)

# Upper bound constraints
model.addConstr(5 * x['granola bars'] + 20 * x['potatoes'] <= 176)
model.addConstr(9 * x['hamburgers'] + 24 * x['eggs'] <= 101)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] <= 171)
model.addConstr(20 * x['potatoes'] + 4 * x['black beans'] <= 161)
model.addConstr(20 * x['potatoes'] + 24 * x['eggs'] <= 181)
model.addConstr(9 * x['hamburgers'] + 4 * x['black beans'] <= 148)
model.addConstr(9 * x['hamburgers'] + 20 * x['potatoes'] + 24 * x['eggs'] <= 165)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 24 * x['eggs'] <= 108)
model.addConstr(9 * x['hamburgers'] + 20 * x['potatoes'] + 4 * x['black beans'] <= 92)
model.addConstr(5 * x['granola bars'] + 4 * x['black beans'] + 24 * x['eggs'] <= 99)
model.addConstr(5 * x['granola bars'] + 9 * x['hamburgers'] + 20 * x['potatoes'] + 4 * x['black beans'] + 24 * x['eggs'] <= 99)
model.addConstr(26 * x['granola bars'] + 26 * x['hamburgers'] <= 225)
model.addConstr(26 * x['granola bars'] + 8 * x['potatoes'] <= 193)
model.addConstr(26 * x['granola bars'] + 8 * x['potatoes'] + 8 * x['black beans'] <= 71)
model.addConstr(26 * x['granola bars'] + 26 * x['hamburgers'] + 8 * x['potatoes'] + 8 * x['black beans'] + 3 * x['eggs'] <= 71)


# Optimize the model
model.optimize()

# Print the results
if model.status == GRB.OPTIMAL:
    print("Optimal solution found:")
    for food in foods:
        print(f"{food}: {x[food].x}")
    print(f"Objective value: {model.objVal}")
elif model.status == GRB.INFEASIBLE:
    print("Model is infeasible.")
else:
    print(f"Optimization terminated with status {model.status}")

```