import os import gradio as gr import pandas as pd import matplotlib.pyplot as plt import matplotlib.font_manager as fm from config import DEFAULT_ICR, DEFAULT_ISF from insulin_calc import calculate_insulin_dose from sqlite_handler import save_result_to_db from carb_calc import calculate_actual_carbs from font_setup import font_properties from ui.ui_history_tab import create_history_tab from datetime import datetime, timedelta, timezone def get_now_jst(): JST = timezone(timedelta(hours=9)) return datetime.now(JST) def get_now_jst_str(): return get_now_jst().strftime("%Y-%m-%d %H:%M") def get_dynamic_icr(hour): return 9.6 if 6 <= hour < 11 else 12.5 def get_default_timing_id(hour): if 7 <= hour < 10: return 1 # 朝食 elif 11 <= hour < 14: return 2 # 昼食 elif 14 <= hour < 18: return 4 # おやつ elif 18 <= hour < 21: return 3 # 夕食(夜食から変更) elif 22 <= hour or hour < 1: return 6 # 寝前 else: return 5 # 追加 def process_input(carb_grams, current_bg): now = get_now_jst() icr_value = get_dynamic_icr(now.hour) try: current_bg = float(current_bg) except ValueError: return "血糖値は必須です。数値を入力してください。", "", "" if carb_grams is None or carb_grams == "": carb_grams = 0.0 try: carb_grams = float(carb_grams) except ValueError: return "炭水化物量が無効です", "", "" result = calculate_insulin_dose(carb_grams, current_bg) return f""" ## 推奨インスリン計算 - 炭水化物用インスリン: {result['carb_insulin']} 単位 - 補正インスリン: {result['correction_insulin']} 単位 - 合計インスリン: {result['total_insulin']} 単位 - 目標血糖値: {result['expected_bg']} mg/dL """, DEFAULT_ICR, DEFAULT_ISF def record_to_db(carb_grams, current_bg, actual_insulin, timing_id, timestamp_text): now = get_now_jst() icr_value = get_dynamic_icr(now.hour) try: current_bg = float(current_bg) carb_grams = float(carb_grams) if carb_grams else 0.0 actual_insulin = float(actual_insulin) if actual_insulin else 0.0 except ValueError: return "数値を正しく入力してください。" result = calculate_insulin_dose(carb_grams, current_bg) return save_result_to_db( carb_grams, current_bg, DEFAULT_ICR, DEFAULT_ISF, result, actual_insulin, timing_id, timestamp_text ) def create_ui(): with gr.Blocks(title="血糖値管理システム") as app: gr.Markdown("# 血糖値管理システム") with gr.Tab("血糖・インスリン記録"): with gr.Row(): with gr.Column(): now = get_now_jst() icr_value = get_dynamic_icr(now.hour) bg = gr.Number(label="現在の血糖値 (mg/dL)", value=120) carb = gr.Number(label="糖質 (g)(任意)", value=None) icr = gr.Number(label="ICR", value=icr_value, interactive=False) isf = gr.Number(label="ISF", value=DEFAULT_ISF, interactive=False) btn_calc = gr.Button("計算") out = gr.Markdown() with gr.Column(): actual_input = gr.Number(label="実際インスリン量 (単位)(任意)", value=None) default_timing_id = get_default_timing_id(now.hour) timing_input = gr.Radio( label="インスリンタイミング", choices=[("朝食", 1), ("昼食", 2), ("夜食", 3), ("おやつ", 4), ("追加", 5), ("寝前", 6)], value=default_timing_id ) timestamp_input = gr.Textbox(label="記録時刻(YYYY-MM-DD HH:MM)(任意)", value=get_now_jst_str, placeholder="空欄で現在時刻") btn_record = gr.Button("記録") out2 = gr.Textbox() btn_calc.click(fn=process_input, inputs=[carb, bg], outputs=[out, icr, isf]) btn_record.click(fn=record_to_db, inputs=[carb, bg, actual_input, timing_input, timestamp_input], outputs=out2) with gr.Tab("炭水化物量計算"): std_food = gr.Number(label="標準食べ物量 (g)", value=100) std_carb = gr.Number(label="表示炭水化物量 (g)", value=15) actual = gr.Number(label="実際食べた量 (g)", value=50) carb_result = gr.Textbox() btn_carb = gr.Button("計算") btn_carb.click(fn=calculate_actual_carbs, inputs=[std_food, std_carb, actual], outputs=carb_result) with gr.Tab("履歴管理"): create_history_tab() return app