Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -31,7 +31,7 @@ GI_RANGES = {
|
|
| 31 |
"high": (70, 100)
|
| 32 |
}
|
| 33 |
|
| 34 |
-
# Utility Functions (unchanged
|
| 35 |
def estimate_gi_timing(gi_value: Optional[int]) -> tuple[float, float]:
|
| 36 |
if gi_value is None:
|
| 37 |
return 1.0, 2.5
|
|
@@ -77,12 +77,16 @@ def classify_food(image):
|
|
| 77 |
print(f"Classify food error: {e}")
|
| 78 |
return "unknown"
|
| 79 |
|
| 80 |
-
def get_food_nutrition(food_name: str, food_data: pd.DataFrame, weight_grams: Optional[float] = None) -> Optional[Dict[str, Any]]:
|
| 81 |
food_name_lower = food_name.lower().strip()
|
| 82 |
matches = get_close_matches(food_name_lower, food_data['food_name'].tolist(), n=1, cutoff=0.6)
|
|
|
|
| 83 |
|
| 84 |
if matches:
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
| 86 |
base_carbs = float(matched_row.get('unit_serving_carb_g', matched_row.get('carb_g', 0.0)))
|
| 87 |
serving_size = matched_row.get('servings_unit', 'unknown')
|
| 88 |
gi_value = matched_row.get('glycemic_index', None)
|
|
@@ -94,10 +98,9 @@ def get_food_nutrition(food_name: str, food_data: pd.DataFrame, weight_grams: Op
|
|
| 94 |
except (ValueError, TypeError):
|
| 95 |
gi_value = None
|
| 96 |
|
| 97 |
-
# Adjust portion based on weight in grams if provided
|
| 98 |
if weight_grams and serving_size != 'unknown':
|
| 99 |
try:
|
| 100 |
-
serving_weight = float(matched_row.get('serving_weight_grams', 100))
|
| 101 |
portion_size = weight_grams / serving_weight
|
| 102 |
except (ValueError, TypeError):
|
| 103 |
portion_size = 1.0
|
|
@@ -106,7 +109,7 @@ def get_food_nutrition(food_name: str, food_data: pd.DataFrame, weight_grams: Op
|
|
| 106 |
|
| 107 |
adjusted_carbs = base_carbs * portion_size
|
| 108 |
|
| 109 |
-
|
| 110 |
'matched_food': matched_row['food_name'],
|
| 111 |
'category': matched_row.get('primarysource', 'unknown'),
|
| 112 |
'subcategory': 'unknown',
|
|
@@ -117,7 +120,8 @@ def get_food_nutrition(food_name: str, food_data: pd.DataFrame, weight_grams: Op
|
|
| 117 |
'notes': 'none',
|
| 118 |
'glycemic_index': gi_value
|
| 119 |
}
|
| 120 |
-
|
|
|
|
| 121 |
|
| 122 |
def determine_gi_level(gi_value: Optional[int]) -> str:
|
| 123 |
if gi_value is None:
|
|
@@ -188,7 +192,7 @@ def calculate_insulin_needs(carbs: float, glucose_current: float, glucose_target
|
|
| 188 |
}
|
| 189 |
|
| 190 |
def create_detailed_report(nutrition_info: Dict[str, Any], insulin_info: Dict[str, Any],
|
| 191 |
-
current_basal_rate: float) -> tuple[str, str, str]:
|
| 192 |
gi_level = determine_gi_level(nutrition_info.get('glycemic_index'))
|
| 193 |
peak_time, duration = estimate_gi_timing(nutrition_info.get('glycemic_index'))
|
| 194 |
|
|
@@ -203,6 +207,7 @@ def create_detailed_report(nutrition_info: Dict[str, Any], insulin_info: Dict[st
|
|
| 203 |
- Carbs per Serving: {nutrition_info['base_carbs']}g
|
| 204 |
- Portion Multiplier: {nutrition_info['portion_multiplier']}x
|
| 205 |
- Total Carbs: {nutrition_info['adjusted_carbs']}g
|
|
|
|
| 206 |
"""
|
| 207 |
|
| 208 |
insulin_details = f"""
|
|
@@ -235,17 +240,15 @@ def diabetes_dashboard(initial_glucose, food_image, food_name_input, weight_gram
|
|
| 235 |
if food_data.empty:
|
| 236 |
return "Error loading food data", None, None, None, None
|
| 237 |
|
| 238 |
-
# Determine food name: use manual input if provided, otherwise classify from image
|
| 239 |
if food_name_input and food_name_input.strip():
|
| 240 |
food_name = food_name_input.strip()
|
| 241 |
else:
|
| 242 |
food_name = classify_food(food_image)
|
| 243 |
|
| 244 |
-
|
| 245 |
-
nutrition_info = get_food_nutrition(food_name, food_data, weight_grams)
|
| 246 |
|
| 247 |
if not nutrition_info:
|
| 248 |
-
return
|
| 249 |
|
| 250 |
try:
|
| 251 |
basal_rates = json.loads(basal_rates_input)
|
|
@@ -261,9 +264,8 @@ def diabetes_dashboard(initial_glucose, food_image, food_name_input, weight_gram
|
|
| 261 |
return insulin_info['error'], None, None, None, None
|
| 262 |
|
| 263 |
current_basal_rate = get_basal_rate(12, basal_rates)
|
| 264 |
-
glucose_meal_details, insulin_details, basal_details = create_detailed_report(nutrition_info, insulin_info, current_basal_rate)
|
| 265 |
|
| 266 |
-
# Glucose Prediction (unchanged)
|
| 267 |
hours = list(range(time_hours))
|
| 268 |
glucose_levels = []
|
| 269 |
current_glucose = initial_glucose
|
|
@@ -291,7 +293,7 @@ def diabetes_dashboard(initial_glucose, food_image, food_name_input, weight_gram
|
|
| 291 |
|
| 292 |
return glucose_meal_details, insulin_details, basal_details, insulin_info['total_bolus'], fig
|
| 293 |
|
| 294 |
-
#
|
| 295 |
with gr.Blocks(title="Type 1 Diabetes Management Dashboard") as app:
|
| 296 |
gr.Markdown("# Type 1 Diabetes Management Dashboard")
|
| 297 |
|
|
|
|
| 31 |
"high": (70, 100)
|
| 32 |
}
|
| 33 |
|
| 34 |
+
# Utility Functions (mostly unchanged)
|
| 35 |
def estimate_gi_timing(gi_value: Optional[int]) -> tuple[float, float]:
|
| 36 |
if gi_value is None:
|
| 37 |
return 1.0, 2.5
|
|
|
|
| 77 |
print(f"Classify food error: {e}")
|
| 78 |
return "unknown"
|
| 79 |
|
| 80 |
+
def get_food_nutrition(food_name: str, food_data: pd.DataFrame, weight_grams: Optional[float] = None) -> tuple[Optional[Dict[str, Any]], str]:
|
| 81 |
food_name_lower = food_name.lower().strip()
|
| 82 |
matches = get_close_matches(food_name_lower, food_data['food_name'].tolist(), n=1, cutoff=0.6)
|
| 83 |
+
correction_note = ""
|
| 84 |
|
| 85 |
if matches:
|
| 86 |
+
corrected_name = matches[0]
|
| 87 |
+
if corrected_name != food_name_lower:
|
| 88 |
+
correction_note = f"Note: '{food_name}' corrected to '{corrected_name}'"
|
| 89 |
+
matched_row = food_data[food_data['food_name'] == corrected_name].iloc[0]
|
| 90 |
base_carbs = float(matched_row.get('unit_serving_carb_g', matched_row.get('carb_g', 0.0)))
|
| 91 |
serving_size = matched_row.get('servings_unit', 'unknown')
|
| 92 |
gi_value = matched_row.get('glycemic_index', None)
|
|
|
|
| 98 |
except (ValueError, TypeError):
|
| 99 |
gi_value = None
|
| 100 |
|
|
|
|
| 101 |
if weight_grams and serving_size != 'unknown':
|
| 102 |
try:
|
| 103 |
+
serving_weight = float(matched_row.get('serving_weight_grams', 100))
|
| 104 |
portion_size = weight_grams / serving_weight
|
| 105 |
except (ValueError, TypeError):
|
| 106 |
portion_size = 1.0
|
|
|
|
| 109 |
|
| 110 |
adjusted_carbs = base_carbs * portion_size
|
| 111 |
|
| 112 |
+
nutrition_info = {
|
| 113 |
'matched_food': matched_row['food_name'],
|
| 114 |
'category': matched_row.get('primarysource', 'unknown'),
|
| 115 |
'subcategory': 'unknown',
|
|
|
|
| 120 |
'notes': 'none',
|
| 121 |
'glycemic_index': gi_value
|
| 122 |
}
|
| 123 |
+
return nutrition_info, correction_note
|
| 124 |
+
return None, f"No close match found for '{food_name}'"
|
| 125 |
|
| 126 |
def determine_gi_level(gi_value: Optional[int]) -> str:
|
| 127 |
if gi_value is None:
|
|
|
|
| 192 |
}
|
| 193 |
|
| 194 |
def create_detailed_report(nutrition_info: Dict[str, Any], insulin_info: Dict[str, Any],
|
| 195 |
+
current_basal_rate: float, correction_note: str) -> tuple[str, str, str]:
|
| 196 |
gi_level = determine_gi_level(nutrition_info.get('glycemic_index'))
|
| 197 |
peak_time, duration = estimate_gi_timing(nutrition_info.get('glycemic_index'))
|
| 198 |
|
|
|
|
| 207 |
- Carbs per Serving: {nutrition_info['base_carbs']}g
|
| 208 |
- Portion Multiplier: {nutrition_info['portion_multiplier']}x
|
| 209 |
- Total Carbs: {nutrition_info['adjusted_carbs']}g
|
| 210 |
+
{correction_note}
|
| 211 |
"""
|
| 212 |
|
| 213 |
insulin_details = f"""
|
|
|
|
| 240 |
if food_data.empty:
|
| 241 |
return "Error loading food data", None, None, None, None
|
| 242 |
|
|
|
|
| 243 |
if food_name_input and food_name_input.strip():
|
| 244 |
food_name = food_name_input.strip()
|
| 245 |
else:
|
| 246 |
food_name = classify_food(food_image)
|
| 247 |
|
| 248 |
+
nutrition_info, correction_note = get_food_nutrition(food_name, food_data, weight_grams)
|
|
|
|
| 249 |
|
| 250 |
if not nutrition_info:
|
| 251 |
+
return correction_note, None, None, None, None
|
| 252 |
|
| 253 |
try:
|
| 254 |
basal_rates = json.loads(basal_rates_input)
|
|
|
|
| 264 |
return insulin_info['error'], None, None, None, None
|
| 265 |
|
| 266 |
current_basal_rate = get_basal_rate(12, basal_rates)
|
| 267 |
+
glucose_meal_details, insulin_details, basal_details = create_detailed_report(nutrition_info, insulin_info, current_basal_rate, correction_note)
|
| 268 |
|
|
|
|
| 269 |
hours = list(range(time_hours))
|
| 270 |
glucose_levels = []
|
| 271 |
current_glucose = initial_glucose
|
|
|
|
| 293 |
|
| 294 |
return glucose_meal_details, insulin_details, basal_details, insulin_info['total_bolus'], fig
|
| 295 |
|
| 296 |
+
# Gradio Interface (unchanged)
|
| 297 |
with gr.Blocks(title="Type 1 Diabetes Management Dashboard") as app:
|
| 298 |
gr.Markdown("# Type 1 Diabetes Management Dashboard")
|
| 299 |
|