DeepWeek commited on
Commit
714c84b
·
verified ·
1 Parent(s): 471cafc

Upload 9 files

Browse files
Files changed (9) hide show
  1. carb_calc.py +13 -0
  2. config.py +18 -0
  3. db_init.py +110 -0
  4. font_setup.py +17 -0
  5. hf_db_sync.py +28 -0
  6. insulin_calc.py +14 -0
  7. requirements.txt +4 -0
  8. sqlite_handler.py +52 -0
  9. ui.py +88 -0
carb_calc.py ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ def calculate_actual_carbs(std_food_weight, std_carb, actual_weight):
3
+ try:
4
+ std_food_weight = float(std_food_weight)
5
+ std_carb = float(std_carb)
6
+ actual_weight = float(actual_weight)
7
+ if std_food_weight <= 0:
8
+ return "標準食べ物量は0より大きい値を入力してください"
9
+ ratio = actual_weight / std_food_weight
10
+ actual_carb = std_carb * ratio
11
+ return f"実際の炭水化物量: {actual_carb:.1f} g"
12
+ except ValueError:
13
+ return "すべての項目に数値を入力してください"
config.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ from huggingface_hub import hf_hub_download
4
+ import sqlite3
5
+
6
+ #DataSet設定
7
+ HF_TOKEN = os.getenv("bloodglucose")
8
+ REPO_ID = "DeepWeek/BloodManagement"
9
+ DATA_FILE_HUB = "blood_glucose_data.csv"
10
+ DATA_FILE_LOCAL = f"./{DATA_FILE_HUB}"
11
+ DB_FILENAME = "blood_records.db"
12
+ LOCAL_DB_PATH = f"./{DB_FILENAME}"
13
+ #初期値
14
+ DEFAULT_USER_ID = "0001"
15
+ DEFAULT_ICR = 15
16
+ DEFAULT_ISF = 80
17
+ TARGET_BG = 100
18
+ TIME_WINDOW = 5
db_init.py ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import sqlite3
2
+ from config import DB_PATH,HF_TOKEN, REPO_ID, DATA_FILE_HUB, DATA_FILE_LOCAL, DEFAULT_USER_ID
3
+ import pandas as pd
4
+
5
+ def init_db(db_path):
6
+ conn = sqlite3.connect(db_path)
7
+ cursor = conn.cursor()
8
+
9
+ cursor.execute("""
10
+ CREATE TABLE IF NOT EXISTS timing (
11
+ id INTEGER PRIMARY KEY,
12
+ label TEXT NOT NULL
13
+ )
14
+ """)
15
+
16
+ cursor.execute("""
17
+ CREATE TABLE IF NOT EXISTS records (
18
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
19
+ user_id TEXT,
20
+ timestamp TEXT,
21
+ carbs REAL,
22
+ current_bg REAL,
23
+ icr REAL,
24
+ isf REAL,
25
+ carb_insulin REAL,
26
+ correction_insulin REAL,
27
+ total_insulin REAL,
28
+ target_bg REAL,
29
+ timing_id INTEGER,
30
+ FOREIGN KEY (timing_id) REFERENCES timing(id)
31
+ )
32
+ """)
33
+
34
+ timing_data = [
35
+ (1, "朝食"), (2, "昼食"), (3, "夜食"),
36
+ (4, "おやつ"), (5, "追加"), (6, "寝前")
37
+ ]
38
+ cursor.executemany("INSERT OR IGNORE INTO timing (id, label) VALUES (?, ?)", timing_data)
39
+
40
+ conn.commit()
41
+ conn.close()
42
+
43
+
44
+ ###############################CSVからDBにデータ移行########################################
45
+ # 1. DB準備
46
+ hf_db_sync.download_and_prepare_db()
47
+
48
+ # 2. CSV初期化
49
+ def initialize_data_file():
50
+ try:
51
+ hf_hub_download(
52
+ repo_id=REPO_ID,
53
+ filename=DATA_FILE_HUB,
54
+ local_dir="./",
55
+ repo_type="dataset",
56
+ token=HF_TOKEN
57
+ )
58
+ print("✅ 既存のCSVファイルを取得しました")
59
+ except Exception as e:
60
+ print(f"⚠️ CSVが取得できなかったため、新規作成します: {e}")
61
+ df = pd.DataFrame(columns=[
62
+ 'user_id', 'timestamp', 'carbs', 'current_bg', 'icr', 'isf',
63
+ 'carb_insulin', 'correction_insulin', 'total_insulin', 'target_bg', 'timing'
64
+ ])
65
+ df.to_csv(DATA_FILE_LOCAL, index=False)
66
+
67
+ initialize_data_file()
68
+
69
+ # 3. CSV読み込みと変換
70
+ csv_path = DATA_FILE_LOCAL
71
+ df = pd.read_csv(csv_path)
72
+
73
+ timing_map = {
74
+ "朝食": 1, "昼食": 2, "夜食": 3,
75
+ "おやつ": 4, "追加": 5, "寝前": 6,
76
+ None: None, "": None
77
+ }
78
+
79
+ if "timing" in df.columns:
80
+ df["timing_id"] = df["timing"].map(timing_map)
81
+ df.drop(columns=["timing"], inplace=True)
82
+ else:
83
+ df["timing_id"] = None
84
+
85
+ # 4. DBに書き込み
86
+ conn = sqlite3.connect(LOCAL_DB_PATH)
87
+ df.to_sql("records", conn, if_exists="append", index=False)
88
+ conn.close()
89
+
90
+ print(f"✅ {len(df)} 行を SQLite に移行しました")
91
+
92
+ # 5. HF Dataset へアップロード
93
+ hf_db_sync.upload_db_to_dataset()
94
+
95
+
96
+ ##############DB内容確認#########################
97
+ hf_db_sync.download_and_prepare_db()
98
+
99
+ conn = sqlite3.connect(LOCAL_DB_PATH) # ← あなたのDBパスに変更
100
+ cursor = conn.cursor()
101
+
102
+ cursor.execute("SELECT count(*) FROM records")
103
+ tables = cursor.fetchall()
104
+
105
+ conn.close()
106
+
107
+ print("📋 テーブル一覧:")
108
+ for t in tables:
109
+ print("-", t[0])
110
+
font_setup.py ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import os
3
+ import matplotlib.pyplot as plt
4
+ import matplotlib.font_manager as fm
5
+
6
+ # Install Japanese fonts
7
+ os.system("apt-get update && apt-get install -y fonts-noto-cjk")
8
+
9
+ # Set font path and apply
10
+ font_path = "/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc"
11
+ if os.path.exists(font_path):
12
+ font_prop = fm.FontProperties(fname=font_path)
13
+ plt.rcParams["font.family"] = font_prop.get_name()
14
+ print(f"✅ Japanese font applied: {font_prop.get_name()}")
15
+ else:
16
+ print("❌ Japanese font not found")
17
+ font_properties = font_prop if os.path.exists(font_path) else None
hf_db_sync.py ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # hf_db_sync.py
2
+
3
+ from huggingface_hub import hf_hub_download, HfApi
4
+ import pandas as pd
5
+ import sqlite3
6
+ import shutil
7
+ import os
8
+ from config import REPO_ID,HF_TOKEN,DB_FILENAME,LOCAL_DB_PATH
9
+
10
+ def download_and_prepare_db():
11
+ db_cache_path = hf_hub_download(
12
+ repo_id=REPO_ID,
13
+ filename=DB_FILENAME,
14
+ repo_type="dataset",
15
+ token=HF_TOKEN,
16
+ )
17
+ if not os.path.exists(LOCAL_DB_PATH):
18
+ shutil.copy(db_cache_path, LOCAL_DB_PATH)
19
+
20
+ def upload_db_to_dataset():
21
+ api = HfApi()
22
+ api.upload_file(
23
+ path_or_fileobj=LOCAL_DB_PATH,
24
+ path_in_repo=DB_FILENAME,
25
+ repo_id=REPO_ID,
26
+ repo_type="dataset",
27
+ token=HF_TOKEN,
28
+ )
insulin_calc.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ from config import DEFAULT_ICR, DEFAULT_ISF, TARGET_BG
3
+
4
+ def calculate_insulin_dose(carb_grams, current_bg, icr=DEFAULT_ICR, isf=DEFAULT_ISF):
5
+ carb_insulin = carb_grams / icr
6
+ bg_difference = current_bg - TARGET_BG
7
+ correction_insulin = max(0, bg_difference / isf)
8
+ total_insulin = carb_insulin + correction_insulin
9
+ return {
10
+ 'carb_insulin': round(carb_insulin, 1),
11
+ 'correction_insulin': round(correction_insulin, 1),
12
+ 'total_insulin': round(total_insulin, 1),
13
+ 'expected_bg': TARGET_BG
14
+ }
requirements.txt ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ gradio
2
+ pandas
3
+ matplotlib
4
+ huggingface_hub
sqlite_handler.py ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import sqlite3
3
+ from datetime import datetime, timedelta, timezone
4
+ from config import LOCAL_DB_PATH
5
+ import hf_db_sync
6
+
7
+ DEFAULT_USER_ID = "0001"
8
+
9
+ def save_result_to_db(carb_grams, current_bg, icr, isf, result, actual_insulin, timing_id):
10
+ hf_db_sync.download_and_prepare_db()
11
+
12
+ JST = timezone(timedelta(hours=9))
13
+ timestamp = datetime.now(JST).strftime('%Y-%m-%d %H:%M:%S')
14
+
15
+ conn = sqlite3.connect(LOCAL_DB_PATH)
16
+ cursor = conn.cursor()
17
+
18
+ # recordsテーブルに保存
19
+ cursor.execute("""
20
+ INSERT INTO records (
21
+ user_id, timestamp, carbs, current_bg, icr, isf,
22
+ carb_insulin, correction_insulin, total_insulin, target_bg, timing_id
23
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
24
+ """, (
25
+ DEFAULT_USER_ID,
26
+ timestamp,
27
+ carb_grams,
28
+ current_bg,
29
+ icr,
30
+ isf,
31
+ result["carb_insulin"],
32
+ result["correction_insulin"],
33
+ actual_insulin,
34
+ result["expected_bg"],
35
+ timing_id
36
+ ))
37
+
38
+ conn.commit()
39
+ conn.close()
40
+
41
+ hf_db_sync.upload_db_to_dataset()
42
+
43
+ return f"✅ 記録しました(インスリン {actual_insulin} 単位, タイミング ID: {timing_id})"
44
+
45
+ def fetch_records():
46
+ conn = sqlite3.connect(LOCAL_DB_PATH)
47
+ df = None
48
+ try:
49
+ df = conn.execute("SELECT * FROM records").fetchall()
50
+ finally:
51
+ conn.close()
52
+ return df
ui.py ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ import gradio as gr
3
+ import pandas as pd
4
+ import matplotlib.pyplot as plt
5
+ from config import DEFAULT_ICR, DEFAULT_ISF
6
+ from insulin_calc import calculate_insulin_dose
7
+ from sqlite_handler import save_result_to_db
8
+ from carb_calc import calculate_actual_carbs
9
+ from font_setup import font_properties
10
+
11
+ def process_input(carb_grams, current_bg):
12
+ try:
13
+ current_bg = float(current_bg)
14
+ except ValueError:
15
+ return "血糖値は必須です。数値を入力してください。", "", ""
16
+
17
+ if carb_grams is None or carb_grams == "":
18
+ carb_grams = 0.0
19
+ try:
20
+ carb_grams = float(carb_grams)
21
+ except ValueError:
22
+ return "炭水化物量が無効です", "", ""
23
+
24
+ result = calculate_insulin_dose(carb_grams, current_bg)
25
+ return f"""
26
+ ## 推奨インスリン計算
27
+
28
+ - 炭水化物用インスリン: {result['carb_insulin']} 単位
29
+ - 補正インスリン: {result['correction_insulin']} 単位
30
+ - 合計インスリン: {result['total_insulin']} 単位
31
+ - 目標血糖値: {result['expected_bg']} mg/dL
32
+ """, DEFAULT_ICR, DEFAULT_ISF
33
+
34
+ def record_to_db(carb_grams, current_bg, actual_insulin, timing_id):
35
+ try:
36
+ current_bg = float(current_bg)
37
+ carb_grams = float(carb_grams) if carb_grams else 0.0
38
+ actual_insulin = float(actual_insulin) if actual_insulin else 0.0
39
+ except ValueError:
40
+ return "数値を正しく入力してください。"
41
+
42
+ result = calculate_insulin_dose(carb_grams, current_bg)
43
+ return save_result_to_db(
44
+ carb_grams,
45
+ current_bg,
46
+ DEFAULT_ICR,
47
+ DEFAULT_ISF,
48
+ result,
49
+ actual_insulin,
50
+ timing_id
51
+ )
52
+
53
+ def create_ui():
54
+ with gr.Blocks(title="血糖値管理システム") as app:
55
+ gr.Markdown("# 血糖値管理システム")
56
+
57
+ with gr.Tab("血糖・インスリン記録"):
58
+ with gr.Row():
59
+ with gr.Column():
60
+ bg = gr.Number(label="現在の血糖値 (mg/dL)", value=120)
61
+ carb = gr.Number(label="摂取炭水化物量 (g)(任意)", value=None)
62
+ icr = gr.Number(label="ICR", value=DEFAULT_ICR, interactive=False)
63
+ isf = gr.Number(label="ISF", value=DEFAULT_ISF, interactive=False)
64
+ btn_calc = gr.Button("計算")
65
+ out = gr.Markdown()
66
+ with gr.Column():
67
+ actual_input = gr.Number(label="実際インスリン量 (単位)(任意)", value=None)
68
+ timing_input = gr.Dropdown(
69
+ label="インスリンタイミング",
70
+ choices=[("朝食", 1), ("昼食", 2), ("夜食", 3),
71
+ ("おやつ", 4), ("追加", 5), ("寝前", 6)],
72
+ value=1
73
+ )
74
+ btn_record = gr.Button("記録")
75
+ out2 = gr.Textbox()
76
+
77
+ btn_calc.click(fn=process_input, inputs=[carb, bg], outputs=[out, icr, isf])
78
+ btn_record.click(fn=record_to_db, inputs=[carb, bg, actual_input, timing_input], outputs=out2)
79
+
80
+ with gr.Tab("炭水化物量計算"):
81
+ std_food = gr.Number(label="標準食べ物量 (g)", value=100)
82
+ std_carb = gr.Number(label="表示炭水化物量 (g)", value=15)
83
+ actual = gr.Number(label="実際食べた量 (g)", value=50)
84
+ carb_result = gr.Textbox()
85
+ btn_carb = gr.Button("計算")
86
+ btn_carb.click(fn=calculate_actual_carbs, inputs=[std_food, std_carb, actual], outputs=carb_result)
87
+
88
+ return app