amychangster commited on
Commit
48af128
·
verified ·
1 Parent(s): 1913aa0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +387 -109
app.py CHANGED
@@ -85,7 +85,7 @@ def save_to_google_sheets(inputs, a_score, d_score, s_score, t_score, score):
85
  client = gspread.authorize(creds)
86
 
87
  # 2. 開啟指定名稱的試算表 (確保已分享權限給 service account)
88
- sheet = client.open("DASS使用者測試資料").sheet1 # 存於檔案的第一張工作表
89
 
90
 
91
  # 1. 拆分資料:前 3 個是基本資料,後面剩下的 (*rest) 是 12 題答案
@@ -117,6 +117,65 @@ def save_to_google_sheets(inputs, a_score, d_score, s_score, t_score, score):
117
 
118
  sheet.append_row(row_to_add)
119
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  # 定義歷史紀錄功能
122
 
@@ -210,6 +269,124 @@ def make_rank_list(a_score, d_score, s_score):
210
  # In[58]:
211
 
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  # 定義預測功能
214
 
215
  def predict_risk(gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12):
@@ -221,6 +398,15 @@ def predict_risk(gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11,
221
  progress = gr.Progress()
222
  progress(0, desc="模型計算中...")
223
 
 
 
 
 
 
 
 
 
 
224
  cols = ["gender", "age", "familysize", "Q2A", "Q4A", "Q19A", "Q20A", "Q28A", "Q21A", "Q26A", "Q37A", "Q42A", "Q11A", "Q12A", "Q27A"]
225
  input_df = pd.DataFrame([[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12]], columns=cols)
226
 
@@ -320,120 +506,212 @@ custom_css = """
320
  }
321
  """
322
 
323
- with gr.Blocks(theme=theme, css=custom_css) as demo:
324
 
325
- # 建立 Session 狀態 (開啟瀏覽器時初始化為空列表)
 
 
 
 
 
 
326
  history_state = gr.State([])
327
 
328
- # 標題及說明
329
  gr.Markdown("")
330
- gr.HTML(f"""
331
  <div style="text-align: center; font-family: sans-serif;">
332
  <h2 style="font-size: 32px; color: #313230; margin: 0;">🌿心理健康風險程度測試📝</h2>
333
  </div>
334
  """)
335
- gr.HTML(f"""
336
- <div style="text-align: center; font-family: sans-serif;">
337
- <h2 style="font-size: 18px; color: #313230; margin: 0;">歡迎來到心理健康風險程度測試環境!<br>
338
- 本測驗將透過12題問答,替您在5分鐘內簡單計算出潛在的心理健康風險程度。<br>
339
- 請輕鬆填答,無須思慮過度,測驗愉快!</h2>
340
- </div>
341
- """)
342
-
343
- with gr.Column(variant="panel", elem_classes="my-custom-panel"):
344
-
345
- # 輸入區塊1(人口靜態欄位)
346
- gr.Markdown("## Step 1. 請輸入基本資訊")
347
- with gr.Row():
348
- with gr.Column():
349
- name = gr.Textbox(label="暱稱")
350
- gen = gr.Dropdown(choices=["男", "女", "其他"],
351
- label="性別",
352
- value=[])
353
- with gr.Column():
354
- age = gr.Number(label="年齡 (僅限填寫數字)", value ="")
355
- family = gr.Number(label="家庭人數 (僅限填寫數字)", value ="")
356
-
357
-
358
- # 輸入區塊2(測驗題)
359
- gr.Markdown("")
360
- gr.Markdown("## Step 2. 請依自身狀態選擇符合的答案")
361
- q1 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
362
- label="Q1.我感覺到口乾舌燥。")
363
- q2 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
364
- label="Q2.我感到呼吸困難(例如:在沒有體力勞動的情況下,呼吸過度急促或喘不過氣)。")
365
- q3 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
366
- label="Q3.在氣溫不高或沒有體力勞動的情況下,我明顯地流汗(例如:手汗)。")
367
- q4 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
368
- label="Q4.我無緣無故地感到害怕。")
369
- q5 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
370
- label="Q5.我覺得自己接近恐慌發作的邊緣。")
371
- q6 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
372
- label="Q6.我覺得生命沒什麼意義/價值。")
373
- q7 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
374
- label="Q7.我感到垂頭喪氣、情緒低落。")
375
- q8 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
376
- label="Q8.我覺得未來毫無希望。")
377
- q9 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
378
- label="Q9.我發現自己很難打起精神主動去做事。")
379
- q10 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
380
- label="Q10.我發現自己很容易變得心煩意亂。")
381
- q11 = gr.Radio([("��不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
382
- label="Q11.我覺得自己消耗了大量的神經能量(處於高度緊繃狀態)。")
383
- q12 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)],
384
- label="Q12.我發現自己非常易怒(容易焦躁)。")
385
-
386
-
387
- # 確認送出按鈕
388
- sub_button = gr.Button("確認送出", elem_id="my_green_btn")
389
- # 重新測驗按鈕
390
- with gr.Row():
391
- btn_reset = gr.Button("重新測驗", elem_id="my_white_btn")
392
-
393
- # 輸出測試結果
394
- with gr.Row():
395
- out_html = gr.HTML()
396
- out_label = gr.HTML()
397
-
398
- # --- 新增:歷史紀錄呈現區域 ---
399
- with gr.Accordion("查看歷史紀錄", open=False, elem_id="history_panel"):
400
- history_display = gr.HTML(value="目前尚無測驗紀錄")
401
-
402
-
403
- # 按鈕設定
404
- # 1. 確認送出
405
- sub_button.click(fn=predict_risk,
406
- inputs= [gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12],
407
- outputs= [out_html, out_label]
408
- ).then(
409
- fn=update_history,
410
- inputs=[out_html, out_label, history_state],
411
- outputs=[history_display, history_state])
412
-
413
- # 2. 重新測驗 (清空所有輸入與輸出)
414
- # 注意:outputs 必須包含所有輸入的組件
415
- btn_reset.click(
416
- fn=lambda: [None]*15 + ["", ""], # 只清空輸入與目前的顯示結果
417
- inputs=None,
418
- outputs=[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, out_html , out_label]
419
- )
420
-
421
-
422
-
423
-
424
-
425
- gr.Markdown("## 免責聲明")
426
- gr.Markdown("""本測驗結果僅供參考,非屬正規醫療檢驗範疇。
427
- 若對於自身狀況有任何疑慮,敬請尋求正規專業醫療協助!♡第四組關心您♡""")
428
-
429
-
430
- # In[ ]:
431
-
432
-
433
- demo.launch()
434
-
435
-
436
- # In[63]:
437
-
438
 
439
- # 如需免費永久托管,需在終端機模式執行「gradio deploy」部署到 Hugging Face Spaces。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
85
  client = gspread.authorize(creds)
86
 
87
  # 2. 開啟指定名稱的試算表 (確保已分享權限給 service account)
88
+ sheet = client.open("DASS使用者測試資料_個人").sheet1 # 存於檔案的第一張工作表
89
 
90
 
91
  # 1. 拆分資料:前 3 個是基本資料,後面剩下的 (*rest) 是 12 題答案
 
117
 
118
  sheet.append_row(row_to_add)
119
 
120
+ def save_to_google_sheets_full42(inputs, dep_score, anx_score, str_score, overall, answers42):
121
+ scope = ['https://www.googleapis.com/auth/spreadsheets',
122
+ 'https://www.googleapis.com/auth/drive']
123
+
124
+ google_json = os.environ.get("DASS_JSON")
125
+ info = json.loads(google_json)
126
+ creds = Credentials.from_service_account_info(info, scopes=scope)
127
+ client = gspread.authorize(creds)
128
+
129
+ sh = client.open("DASS使用者測試資料_個人")
130
+
131
+ ws_title = "DASS42_完整版"
132
+ try:
133
+ sheet = sh.worksheet(ws_title)
134
+ except gspread.exceptions.WorksheetNotFound:
135
+ sheet = sh.add_worksheet(title=ws_title, rows=2000, cols=60)
136
+
137
+ header = (
138
+ ["測試時間", "性別", "年齡", "家庭人數",
139
+ "焦慮分數", "憂鬱分數", "壓力分數", "總體分數", "整體程度"]
140
+ + [f"Q{i}" for i in range(1, 43)]
141
+ )
142
+
143
+ if sheet.acell("A1").value in (None, ""):
144
+ sheet.update("A1", [header])
145
+
146
+ # ===== 整理資料 =====
147
+ now = datetime.now(tw_timezone).strftime("%Y-%m-%d %H:%M:%S")
148
+
149
+ # inputs = [name, gen, age, family] + answers
150
+ _, gen, age, family = inputs[0], inputs[1], inputs[2], inputs[3]
151
+
152
+ # 若 family 是 15人以上 → 存成 16
153
+ if family == "15人以上":
154
+ family = 16
155
+
156
+ t_score = dep_score + anx_score + str_score
157
+
158
+ row_to_add = [
159
+ now,
160
+ gen,
161
+ age,
162
+ family,
163
+ anx_score,
164
+ dep_score,
165
+ str_score,
166
+ t_score,
167
+ overall
168
+ ]
169
+
170
+ row_to_add.extend(list(answers42))
171
+
172
+ def to_py(v):
173
+ return v.item() if hasattr(v, "item") else v
174
+
175
+ row_to_add = [to_py(x) for x in row_to_add]
176
+
177
+ sheet.append_row(row_to_add)
178
+
179
 
180
  # 定義歷史紀錄功能
181
 
 
269
  # In[58]:
270
 
271
 
272
+
273
+ # DASS-42 官方計分
274
+
275
+ dep_nums = [3,5,10,13,16,17,21,24,26,31,34,37,38,42]
276
+ anx_nums = [2,4,7,9,15,19,20,23,25,28,30,36,40,41]
277
+ str_nums = [1,6,8,11,12,14,18,22,27,29,32,33,35,39]
278
+
279
+ def qcols(nums):
280
+ return [f"Q{n}A" for n in nums]
281
+
282
+ def level_dep(score):
283
+ # DASS-42 Depression
284
+ if score <= 9: return 0
285
+ if score <= 13: return 1
286
+ if score <= 20: return 2
287
+ if score <= 27: return 3
288
+ return 4
289
+
290
+ def level_anx(score):
291
+ # DASS-42 Anxiety
292
+ if score <= 7: return 0
293
+ if score <= 9: return 1
294
+ if score <= 14: return 2
295
+ if score <= 19: return 3
296
+ return 4
297
+
298
+ def level_str(score):
299
+ # DASS-42 Stress
300
+ if score <= 14: return 0
301
+ if score <= 18: return 1
302
+ if score <= 25: return 2
303
+ if score <= 33: return 3
304
+ return 4
305
+
306
+ LEVEL_NAME = {0:"正常", 1:"輕度", 2:"中度", 3:"重度", 4:"極重度"}
307
+
308
+ def overall_severity_v2(d_level, a_level, s_level):
309
+ total = d_level + a_level + s_level
310
+ if (d_level == 4) or (a_level == 4) or (s_level == 4):
311
+ return 2
312
+ if total >= 9:
313
+ return 2
314
+ if (d_level == 3) or (a_level == 3) or (s_level == 3):
315
+ return 1
316
+ if total <= 5:
317
+ return 0
318
+ else:
319
+ return 1
320
+
321
+ OVERALL_NAME = {
322
+ 0:"低度風險",
323
+ 1:"中度風險",
324
+ 2:"高度風險"}
325
+
326
+ OVERALL_COLOR = {
327
+ 0: "#91cd92", # 綠
328
+ 1: "#f59e0b", # 橘
329
+ 2: "#ef4444", # 紅
330
+ }
331
+
332
+ def predict_dass42_full(name, gen, age, family, *answers):
333
+ """
334
+ 完整版:42題官方計分(0-3)
335
+ 回傳:只顯示 Overall(v2)(大字置中)+ 右側排名卡(保留)
336
+ 並寫入 Google Sheet(DASS42_完整版)
337
+ """
338
+ inputs = [name, gen, age, family] + list(answers)
339
+ if any(v is None or v == "" for v in inputs):
340
+ raise gr.Error("⚠️請確保基本資料與 42 題都已填答。")
341
+
342
+ # 建立 Q1A~Q42A
343
+ row = {f"Q{i+1}A": int(answers[i]) for i in range(42)}
344
+
345
+ # 官方三向度分數
346
+ dep_score = sum(row[c] for c in qcols(dep_nums))
347
+ anx_score = sum(row[c] for c in qcols(anx_nums))
348
+ str_score = sum(row[c] for c in qcols(str_nums))
349
+
350
+ # 分級
351
+ dep_level = level_dep(dep_score)
352
+ anx_level = level_anx(anx_score)
353
+ str_level = level_str(str_score)
354
+
355
+ # Overall v2
356
+ overall = overall_severity_v2(dep_level, anx_level, str_level)
357
+
358
+ # 寫入 Google Sheet(42 題)
359
+ # answers42 就是 42 題答案本身
360
+ save_to_google_sheets_full42(
361
+ inputs=[name, gen, age, family],
362
+ dep_score=dep_score,
363
+ anx_score=anx_score,
364
+ str_score=str_score,
365
+ overall=overall,
366
+ answers42=answers
367
+ )
368
+
369
+ # 顏色 + 顯示文字
370
+ color = OVERALL_COLOR.get(overall, "#999999")
371
+ text = OVERALL_NAME.get(overall, str(overall))
372
+
373
+ # 左側大字結果(不含下方說明)
374
+ result_html = f"""
375
+ <div style="text-align:center; font-family:sans-serif; padding: 40px 0;">
376
+ <div style="font-size: 44px; font-weight: 900; color:#313230; margin-bottom: 26px;">
377
+ 您的預測結果為
378
+ </div>
379
+ <div style="font-size: 96px; font-weight: 900; color:{color}; line-height: 1;">
380
+ {text}
381
+ </div>
382
+ </div>
383
+ """
384
+
385
+ # 右邊排名卡
386
+ rank_html = make_rank_list(anx_score, dep_score, str_score)
387
+
388
+ return result_html, rank_html
389
+
390
  # 定義預測功能
391
 
392
  def predict_risk(gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12):
 
398
  progress = gr.Progress()
399
  progress(0, desc="模型計算中...")
400
 
401
+ # age 可能是 int / str,都統一轉 int
402
+ age = int(age)
403
+
404
+ # family 可能是 int / str / "15人以上"
405
+ if family == "15人以上":
406
+ family = 16
407
+ else:
408
+ family = int(family)
409
+
410
  cols = ["gender", "age", "familysize", "Q2A", "Q4A", "Q19A", "Q20A", "Q28A", "Q21A", "Q26A", "Q37A", "Q42A", "Q11A", "Q12A", "Q27A"]
411
  input_df = pd.DataFrame([[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12]], columns=cols)
412
 
 
506
  }
507
  """
508
 
 
509
 
510
+ # UI
511
+
512
+ age_choices = list(range(1, 100)) # 1~99歲
513
+ family_choices = list(range(1, 16)) + ["15人以上"]
514
+
515
+ with gr.Blocks() as demo:
516
+ # Tab1 歷史
517
  history_state = gr.State([])
518
 
 
519
  gr.Markdown("")
520
+ gr.HTML("""
521
  <div style="text-align: center; font-family: sans-serif;">
522
  <h2 style="font-size: 32px; color: #313230; margin: 0;">🌿心理健康風險程度測試📝</h2>
523
  </div>
524
  """)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
525
 
526
+ with gr.Tabs():
527
+
528
+ # =========================================================
529
+ # TAB 1:簡易版(12題|模型)
530
+ # =========================================================
531
+ with gr.TabItem("簡易版 12題"):
532
+
533
+ gr.HTML("""
534
+ <div style="text-align: center; font-family: sans-serif;">
535
+ <h2 style="font-size: 18px; color: #313230; margin: 0;">歡迎來到心理健康風險程度測試環境!<br>
536
+ 本測驗將透過12題問答,替您在5分鐘內簡單計算出潛在的心理健康風險程度。<br>
537
+ 請輕鬆填答,無須思慮過度,測驗愉快!</h2>
538
+ </div>
539
+ """)
540
+
541
+ with gr.Column(variant="panel", elem_classes="my-custom-panel"):
542
+ gr.Markdown("## Step 1. 請輸入基本資訊")
543
+ with gr.Row():
544
+ with gr.Column():
545
+ name = gr.Textbox(label="暱稱")
546
+ gen = gr.Dropdown(choices=["男", "女", "其他"], label="性別")
547
+ with gr.Column():
548
+ age = gr.Dropdown(
549
+ choices=age_choices,
550
+ label="年齡",
551
+ value=None
552
+ )
553
+
554
+ family = gr.Dropdown(
555
+ choices=family_choices,
556
+ label="家庭人數",
557
+ value=None
558
+ )
559
+
560
+ gr.Markdown("## Step 2. 請依自身狀態選擇符合的答案")
561
+ q1 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q1.我感覺到口乾舌燥。")
562
+ q2 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q2.我感到呼吸困難(例如:在沒有體力勞動的情況下,呼吸過度急促或喘不過氣)。")
563
+ q3 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q3.在氣溫不高或沒有體力勞動的情況下,我明顯地流汗(例如:手汗)。")
564
+ q4 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q4.我無緣無故地感到害怕。")
565
+ q5 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q5.我覺得自己接近恐慌發作的邊緣。")
566
+ q6 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q6.我覺得生命沒什麼意義/價值。")
567
+ q7 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q7.我感到垂頭喪氣、情緒低落。")
568
+ q8 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q8.我覺得未來毫無希望。")
569
+ q9 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q9.我發現自己很難打起精神主動去做事。")
570
+ q10 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q10.我發現自己很容易變得心煩意亂。")
571
+ q11 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q11.我覺得自己消耗了大量的神經能量(處於高度緊繃狀態)。")
572
+ q12 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q12.我發現自己非常易怒(容易焦躁)。")
573
+
574
+ sub_button = gr.Button("確認送出", elem_id="my_green_btn")
575
+ btn_reset = gr.Button("重新測驗", elem_id="my_white_btn")
576
+
577
+ with gr.Row():
578
+ out_html = gr.HTML()
579
+ out_label = gr.HTML()
580
+
581
+ with gr.Accordion("查看歷史紀錄", open=False, elem_id="history_panel"):
582
+ history_display = gr.HTML(value="目前尚無測驗紀錄")
583
+
584
+ sub_button.click(
585
+ fn=predict_risk,
586
+ inputs=[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12],
587
+ outputs=[out_html, out_label],
588
+ ).then(
589
+ fn=update_history,
590
+ inputs=[out_html, out_label, history_state],
591
+ outputs=[history_display, history_state],
592
+ )
593
+
594
+ btn_reset.click(
595
+ fn=lambda: [None]*15 + ["", ""],
596
+ inputs=None,
597
+ outputs=[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, out_html, out_label],
598
+ )
599
+
600
+ gr.Markdown("## 免責聲明")
601
+ gr.Markdown("""本測驗結果僅供參考,非屬正規醫療檢驗範疇。
602
+ 若對於自身狀況有任何疑慮,敬請尋求正規專業醫療協助!♡第四組關心您♡""")
603
+
604
+ # =========================================================
605
+ # TAB 2:完整版(42題|官方計分)
606
+ # =========================================================
607
+ with gr.TabItem("完整版 42題"):
608
+
609
+ # Tab2 歷史
610
+ full_history_state = gr.State([])
611
+
612
+ gr.HTML("""
613
+ <div style="text-align: center; font-family: sans-serif; margin-bottom: 6px;">
614
+ <h2 style="font-size: 18px; color: #313230; margin: 0;">
615
+ 歡迎來到 DASS-42 完整版心理測驗!<br>
616
+ 本測驗將依 42 題官方計分規則,計算您的心理狀態並輸出風險程度。<br>
617
+ 請依過去一週的感受作答,測驗愉快!
618
+ </h2>
619
+ </div>
620
+ """)
621
+
622
+ gr.Markdown("## Step 1. 請輸入基本資訊")
623
+ with gr.Row():
624
+ with gr.Column():
625
+ full_name = gr.Textbox(label="暱稱")
626
+ full_gen = gr.Dropdown(choices=["男", "女", "其他"], label="性別")
627
+ with gr.Column():
628
+ full_age = gr.Dropdown(
629
+ choices=age_choices,
630
+ label="年齡",
631
+ value=None
632
+ )
633
+
634
+ full_family = gr.Dropdown(
635
+ choices=family_choices,
636
+ label="家庭人數",
637
+ value=None
638
+ )
639
+
640
+ gr.Markdown("## Step 2. DASS-42(0~3)")
641
+
642
+ dass42_questions = [
643
+ "1. 我發覺自己會因為瑣事而沮喪",
644
+ "2. 我察覺到自己口乾舌燥",
645
+ "3. 我似乎無法經驗任何正向的感受",
646
+ "4. 我經歷過呼吸困難(例如:在沒有耗費體力的情況下仍呼吸過快、呼吸困難)",
647
+ "5. 我似乎就是提不起勁",
648
+ "6. 我傾向對情境過度反應",
649
+ "7. 我有顫抖的感覺(例如:雙腿無力)",
650
+ "8. 我發覺難以放鬆",
651
+ "9. 我發覺我處於讓自己頗焦慮的情況,而當它們結束時我感到紓解",
652
+ "10. 我覺得我沒有什麼可以期待的",
653
+ "11. 我發覺自己頗容易變得沮喪",
654
+ "12. 我覺得我相當費心勞神",
655
+ "13. 我感到傷心且憂鬱",
656
+ "14. 我發覺自己在任何被延誤的情況中(例如:等電梯、等紅綠燈、一直等待)會變得不耐煩",
657
+ "15. 我有頭暈無力的感覺",
658
+ "16. 我覺得我幾乎對任何事情已失去興趣",
659
+ "17. 我覺得我作為一個人沒有多少價值",
660
+ "18. 我覺得我頗敏感",
661
+ "19. 在沒有高溫或耗費體力的情況下,我仍明顯出汗(例如:冒手汗)",
662
+ "20. 我會無緣無故地感到害怕",
663
+ "21. 我覺得人生沒有價值",
664
+ "22. 我發覺難以平靜下來",
665
+ "23. 我有吞嚥的困難",
666
+ "24. 我似乎無法從所做的事情中獲得任何樂趣",
667
+ "25. 在沒有耗費體力的情況下,我仍覺察到我心臟的活動(例如:感覺心率增加、心跳漏拍)",
668
+ "26. 我感到沮喪而消沉",
669
+ "27. 我發覺自己煩躁易怒",
670
+ "28. 我覺得自己快要陷入恐慌",
671
+ "29. 我發覺當某些事物讓我沮喪後,我難以平靜下來",
672
+ "30. 我怕自己會被某些瑣碎但不熟悉的任務給難倒",
673
+ "31. 我無法對任何事物變得熱衷",
674
+ "32. 我發覺難以容忍自己正在做的事情被打擾",
675
+ "33. 我處於神經緊繃的狀態",
676
+ "34. 我覺得我頗沒有價值",
677
+ "35. 我不能容忍任何阻礙我繼續做事的事物",
678
+ "36. 我感到懼怕",
679
+ "37. 我看不到未來可以期盼的事物",
680
+ "38. 我覺得人生是沒有意義的",
681
+ "39. 我發覺自己變得激動不安",
682
+ "40. 我對於可能會讓我恐慌或是出糗的情境感到擔憂",
683
+ "41. 我有過顫抖的經驗(例如:手部)",
684
+ "42. 我發覺難以產生動力去做事",
685
+ ]
686
+
687
+ full_q_widgets = []
688
+ for q_text in dass42_questions:
689
+ full_q_widgets.append(
690
+ gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label=q_text)
691
+ )
692
+
693
+ full_submit = gr.Button("確認送出(計算完整版分數)", elem_id="my_green_btn")
694
+
695
+ with gr.Row():
696
+ full_out_html = gr.HTML()
697
+ full_out_rank = gr.HTML()
698
+
699
+ with gr.Accordion("查看歷史紀錄(完整版)", open=False, elem_id="history_panel"):
700
+ full_history_display = gr.HTML(value="目前尚無測驗紀錄")
701
+
702
+ full_submit.click(
703
+ fn=predict_dass42_full,
704
+ inputs=[full_name, full_gen, full_age, full_family] + full_q_widgets,
705
+ outputs=[full_out_html, full_out_rank],
706
+ ).then(
707
+ fn=update_history,
708
+ inputs=[full_out_html, full_out_rank, full_history_state],
709
+ outputs=[full_history_display, full_history_state],
710
+ )
711
+
712
+ gr.Markdown("## 免責聲明")
713
+ gr.Markdown("""本測驗結果僅供參考,非屬正規醫療檢驗範疇。
714
+ 若對於自身狀況有任何疑慮,敬請尋求正規專業醫療協助!♡第四組關心您♡""")
715
+
716
+
717
+ demo.launch(theme=theme, css=custom_css)