File size: 7,954 Bytes
86a293a
 
 
 
3192101
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
077d4ce
 
 
86a293a
 
 
71879f6
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
077d4ce
 
 
3192101
 
86a293a
3192101
 
86a293a
3192101
86a293a
3192101
 
 
86a293a
3192101
86a293a
3192101
 
 
 
 
86a293a
 
3192101
 
 
 
 
 
077d4ce
3192101
 
 
 
 
 
 
 
 
86a293a
077d4ce
86a293a
 
 
077d4ce
 
86a293a
077d4ce
86a293a
077d4ce
 
3192101
 
 
86a293a
fee6ea2
3192101
71879f6
 
3192101
86a293a
fee6ea2
 
 
 
 
 
 
 
 
 
 
 
71879f6
3192101
077d4ce
 
86a293a
fee6ea2
077d4ce
86a293a
077d4ce
fee6ea2
71879f6
 
86a293a
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
import gradio as gr
import numpy as np
from scipy.optimize import linprog

# Example data: Nutritional Information and Cost for the healthiest dishes
nutritional_data = {
    "Idli with Vegetable Sambar": {
        "Energy (kcal)": 100, "Protein (g)": 5.5, "Fat (g)": 1.5, "Carbohydrate (g)": 17.0, "Fiber (g)": 3.0, 
        "Calcium (mg)": 35, "Iron (mg)": 1.0, "Vitamin C (mg)": 8.0,
        "Chennai": 50, "Bengaluru": 55, "Hyderabad": 50, "New Delhi": 60
    },
    "Khichdi": {
        "Energy (kcal)": 120, "Protein (g)": 4.0, "Fat (g)": 2.5, "Carbohydrate (g)": 20.0, "Fiber (g)": 2.5, 
        "Calcium (mg)": 40, "Iron (mg)": 1.0, "Vitamin C (mg)": 5.0,
        "Chennai": 60, "Bengaluru": 65, "Hyderabad": 60, "New Delhi": 70
    },
    "Tandoori Chicken": {
        "Energy (kcal)": 150, "Protein (g)": 18.0, "Fat (g)": 7.0, "Carbohydrate (g)": 3.0, "Fiber (g)": 0.5, 
        "Calcium (mg)": 15, "Iron (mg)": 1.2, "Vitamin C (mg)": 1.5,
        "Chennai": 150, "Bengaluru": 160, "Hyderabad": 150, "New Delhi": 180
    },
    "Palak Paneer": {
        "Energy (kcal)": 140, "Protein (g)": 7.5, "Fat (g)": 10.0, "Carbohydrate (g)": 6.0, "Fiber (g)": 3.0, 
        "Calcium (mg)": 200, "Iron (mg)": 3.0, "Vitamin C (mg)": 15.0,
        "Chennai": 100, "Bengaluru": 110, "Hyderabad": 100, "New Delhi": 120
    },
    "Raita": {
        "Energy (kcal)": 60, "Protein (g)": 3.5, "Fat (g)": 2.0, "Carbohydrate (g)": 6.5, "Fiber (g)": 0.5, 
        "Calcium (mg)": 100, "Iron (mg)": 0.5, "Vitamin C (mg)": 2.0,
        "Chennai": 30, "Bengaluru": 35, "Hyderabad": 30, "New Delhi": 40
    },
    "Rajma": {
        "Energy (kcal)": 140, "Protein (g)": 7.5, "Fat (g)": 5.0, "Carbohydrate (g)": 20.0, "Fiber (g)": 6.0, 
        "Calcium (mg)": 50, "Iron (mg)": 3.5, "Vitamin C (mg)": 4.0,
        "Chennai": 80, "Bengaluru": 90, "Hyderabad": 80, "New Delhi": 100
    },
    "Baingan Bharta": {
        "Energy (kcal)": 70, "Protein (g)": 2.5, "Fat (g)": 3.0, "Carbohydrate (g)": 10.0, "Fiber (g)": 4.0, 
        "Calcium (mg)": 30, "Iron (mg)": 0.7, "Vitamin C (mg)": 6.0,
        "Chennai": 50, "Bengaluru": 55, "Hyderabad": 50, "New Delhi": 60
    },
    "Besan Chilla": {
        "Energy (kcal)": 180, "Protein (g)": 8.0, "Fat (g)": 7.0, "Carbohydrate (g)": 20.0, "Fiber (g)": 5.0, 
        "Calcium (mg)": 30, "Iron (mg)": 2.5, "Vitamin C (mg)": 1.0,
        "Chennai": 60, "Bengaluru": 65, "Hyderabad": 60, "New Delhi": 70
    },
    "Masoor Dal": {
        "Energy (kcal)": 110, "Protein (g)": 7.5, "Fat (g)": 2.0, "Carbohydrate (g)": 16.0, "Fiber (g)": 5.5, 
        "Calcium (mg)": 25, "Iron (mg)": 3.0, "Vitamin C (mg)": 4.0,
        "Chennai": 70, "Bengaluru": 75, "Hyderabad": 70, "New Delhi": 80
    },
    "Upma": {
        "Energy (kcal)": 150, "Protein (g)": 4.0, "Fat (g)": 6.0, "Carbohydrate (g)": 25.0, "Fiber (g)": 3.0, 
        "Calcium (mg)": 30, "Iron (mg)": 1.0, "Vitamin C (mg)": 3.0,
        "Chennai": 40, "Bengaluru": 45, "Hyderabad": 40, "New Delhi": 50
    }
}

def display_dishes_in_city(city):
    """Displays all dishes available in the selected city with their nutritional information and cost."""
    result_str = f"### Available Dishes in {city}:\n"
    for dish, info in nutritional_data.items():
        result_str += f"- **{dish}**\n"
        result_str += f"  - Cost: ₹{info[city]}\n"
        result_str += f"  - Energy: {info['Energy (kcal)']} kcal\n"
        result_str += f"  - Protein: {info['Protein (g)']} g\n"
        result_str += f"  - Fat: {info['Fat (g)']} g\n"
        result_str += f"  - Carbohydrate: {info['Carbohydrate (g)']} g\n"
        result_str += f"  - Fiber: {info['Fiber (g)']} g\n"
        result_str += f"  - Calcium: {info['Calcium (mg)']} mg\n"
        result_str += f"  - Iron: {info['Iron (mg)']} mg\n"
        result_str += f"  - Vitamin C: {info['Vitamin C (mg)']} mg\n\n"
    return result_str

def optimize_nutrition_in_city(city, target_calories, target_protein, max_cost):
    # Extracting cost, calories, and protein data for the selected city
    costs = [nutritional_data[dish][city] for dish in nutritional_data]
    calories = [nutritional_data[dish]["Energy (kcal)"] for dish in nutritional_data]
    proteins = [nutritional_data[dish]["Protein (g)"] for dish in nutritional_data]
    
    # Objective function: Minimize cost
    c = costs
    
    # Inequality constraints (A_ub @ x <= b_ub)
    A_ub = [
        [-cal for cal in calories],  # -calories to ensure sum(calories * x) >= target_calories
        [-prot for prot in proteins],  # -protein to ensure sum(proteins * x) >= target_protein
        costs  # to ensure sum(costs * x) <= max_cost
    ]
    b_ub = [-target_calories, -target_protein, max_cost]
    
    # Bounds for each dish (x >= 0)
    bounds = [(0, None) for _ in costs]

    # Solve the optimization problem
    result = linprog(c, A_ub=A_ub, b_ub=b_ub, bounds=bounds, method='highs')
    
    if result.success:
        selected_dishes = [dish for i, dish in enumerate(nutritional_data) if result.x[i] > 1e-5]
        quantities = result.x
        total_cost = result.fun
        total_calories = sum(cal * q for cal, q in zip(calories, quantities))
        total_protein = sum(prot * q for prot, q in zip(proteins, quantities))
        
        result_str = f"### Selected Dishes in {city} (Quantities):\n"
        for dish, qty in zip(selected_dishes, quantities):
            if qty > 1e-5:
                result_str += f"- **{dish}**: {qty:.2f} portions\n"
        
        result_str += f"\n### Total Cost: ₹{total_cost:.2f}\n"
        result_str += f"### Total Calories: {total_calories:.2f} kcal\n"
        result_str += f"### Total Protein: {total_protein:.2f} g\n"
        
        return result_str
    else:
        return f"No feasible solution found for {city} that meets the nutritional goals within the cost constraints."

# Gradio Interface
def create_interface():
    cities = ["Chennai", "Bengaluru", "Hyderabad", "New Delhi"]
    
    with gr.Blocks() as demo:
        gr.Markdown("# Cost vs. Nutrition Trade-off Optimization in Different Cities")
        
        # User inputs for city, nutritional targets, and cost limit
        city_selector = gr.Dropdown(choices=cities, label="Select City")
        energy_target = gr.Number(label="Target Energy (kcal)", value=500)
        protein_target = gr.Number(label="Target Protein (g)", value=25)
        cost_limit = gr.Number(label="Maximum Cost (₹)", value=300)
        
        toggle_dishes_button = gr.Button("Display Dishes")
        optimize_button = gr.Button("Optimize")
        
        dishes_output = gr.Markdown(label="Available Dishes")
        optimization_output = gr.Markdown(label="Optimization Results")
        
        # Function to toggle the display of dishes
        dishes_visible = False
        
        def toggle_dishes(city):
            nonlocal dishes_visible
            dishes_visible = not dishes_visible
            if dishes_visible:
                toggle_dishes_button.label = "Hide Dishes"
                return display_dishes_in_city(city)
            else:
                toggle_dishes_button.label = "Display Dishes"
                return ""
        
        # Function to handle optimization
        def run_optimization(city, target_calories, target_protein, max_cost):
            return optimize_nutrition_in_city(city, target_calories, target_protein, max_cost)
        
        toggle_dishes_button.click(fn=toggle_dishes, inputs=[city_selector], outputs=dishes_output)
        optimize_button.click(fn=run_optimization, inputs=[city_selector, energy_target, protein_target, cost_limit], outputs=optimization_output)
        
        gr.Row([city_selector, energy_target, protein_target, cost_limit])
        gr.Row(toggle_dishes_button, optimize_button)
        gr.Row(dishes_output)
        gr.Row(optimization_output)
    
    return demo

# Launch the interface
demo = create_interface()
demo.launch(share=True)