File size: 24,884 Bytes
60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae b925ae1 60345ae 48af128 484ea32 48af128 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 0659b60 1ae6917 60345ae 1ae6917 60345ae 1ae6917 48af128 60345ae 1ae6917 60345ae 48af128 0659b60 60345ae 0659b60 60345ae 0659b60 60345ae 0659b60 60345ae 0659b60 60345ae 0659b60 60345ae 1ae6917 60345ae 0659b60 60345ae 0659b60 1ae6917 60345ae 1ae6917 60345ae 1ae6917 60345ae 1ae6917 48af128 1ae6917 48af128 1ae6917 60345ae 48af128 | 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 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 | #!/usr/bin/env python
# coding: utf-8
# 建立環境
# In[50]:
# get_ipython().system('pip install gradio')
# In[51]:
# get_ipython().system('pip install gspread google-auth')
# In[52]:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
import gradio as gr
import sklearn
import pickle
import joblib
import time
import os
import json
import gspread
from sklearn.model_selection import train_test_split, RandomizedSearchCV
from sklearn.compose import ColumnTransformer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import classification_report, confusion_matrix, f1_score, accuracy_score, precision_score, balanced_accuracy_score
from sklearn.ensemble import RandomForestClassifier
from lightgbm import LGBMClassifier
from AutoPreprocess import AutoPreprocess
from google.oauth2.service_account import Credentials
from datetime import datetime, timezone, timedelta
# Gradio 使用者介面
# In[53]:
# 載入模型
import pickle
model_path = os.path.abspath("DASS_model.bin")
with open(model_path, "rb") as f:
model = pickle.load(f)
model
# 定義儲存測試資料的功能
# In[54]:
import os
import json
from datetime import datetime, timezone, timedelta
import gspread
from google.oauth2.service_account import Credentials
# 設定台灣時區
tw_timezone = timezone(timedelta(hours=8))
def save_to_google_sheets(inputs, a_score, d_score, s_score, t_score, score):
# 1. 設定 Google Sheets 存取權限
scope = ['https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive']
# 設定Secret Variables(藏金鑰)
google_json = os.environ.get("DASS_JSON")
info = json.loads(google_json)
creds = Credentials.from_service_account_info(info, scopes=scope)
client = gspread.authorize(creds)
# 2. 開啟指定名稱的試算表 (確保已分享權限給 service account)
sheet = client.open("DASS使用者測試資料").sheet1 # 存於檔案的第一張工作表
# 1. 拆分資料:前 3 個是基本資料,後面剩下的 (*rest) 是 12 題答案
user_info = inputs[:3] # 取得前三個:姓名, 年齡, 性別
q_answers = inputs[3:] # 取得剩下的 12 題
now = datetime.now(tw_timezone).strftime("%Y-%m-%d %H:%M:%S")
# 2. 準備要儲存的資料字典
row_to_add = [
now, # 欄位 A: 測試時間
user_info[0], # 欄位 B: 性別
user_info[1], # 欄位 C: 年齡
user_info[2], # 欄位 D: 家庭人數
a_score, # 欄位 E: 焦慮分數
d_score, # 欄位 F: 憂鬱分數
s_score, # 欄位 G: 壓力分數
t_score, # 欄位 H: 總體分數
score # 欄位 I: 整體程度 (標籤)
]
row_to_add.extend(q_answers) # 加入 Q1-Q12 (J欄以後)
# 4. 追加到試算表最後一行
def to_py(v):
return v.item() if hasattr(v, "item") else v
row_to_add = [to_py(x) for x in row_to_add]
sheet.append_row(row_to_add)
def save_to_google_sheets_full42(inputs, dep_score, anx_score, str_score, overall, answers42):
scope = ['https://www.googleapis.com/auth/spreadsheets',
'https://www.googleapis.com/auth/drive']
google_json = os.environ.get("DASS_JSON")
info = json.loads(google_json)
creds = Credentials.from_service_account_info(info, scopes=scope)
client = gspread.authorize(creds)
sh = client.open("DASS使用者測試資料")
ws_title = "DASS42_完整版"
try:
sheet = sh.worksheet(ws_title)
except gspread.exceptions.WorksheetNotFound:
sheet = sh.add_worksheet(title=ws_title, rows=2000, cols=60)
header = (
["測試時間", "性別", "年齡", "家庭人數",
"焦慮分數", "憂鬱分數", "壓力分數", "總體分數", "整體程度"]
+ [f"Q{i}" for i in range(1, 43)]
)
if sheet.acell("A1").value in (None, ""):
sheet.update("A1", [header])
# ===== 整理資料 =====
now = datetime.now(tw_timezone).strftime("%Y-%m-%d %H:%M:%S")
# inputs = [name, gen, age, family] + answers
_, gen, age, family = inputs[0], inputs[1], inputs[2], inputs[3]
# 若 family 是 15人以上 → 存成 16
if family == "15人以上":
family = 16
t_score = dep_score + anx_score + str_score
row_to_add = [
now,
gen,
age,
family,
anx_score,
dep_score,
str_score,
t_score,
overall
]
row_to_add.extend(list(answers42))
def to_py(v):
return v.item() if hasattr(v, "item") else v
row_to_add = [to_py(x) for x in row_to_add]
sheet.append_row(row_to_add)
# 定義歷史紀錄功能
# In[56]:
def update_history(current_result_1, current_result_2, history_list):
"""
current_result_1 & 2: 來自 predict_risk 的兩個回傳值 (HTML 字串)
history_list: 來自 gr.State 的現有紀錄列表
"""
# 獲取當前時間,格式為:2023-10-27 14:30:05
now = datetime.now(tw_timezone).strftime("%Y-%m-%d %H:%M:%S")
# 組合這次的結果 (假設你想存這兩個 outputs 的組合)
new_entry = f"""
<div style="border-bottom: 2px solid #eee; padding-bottom: 20px; margin-bottom: 20px;">
<div style="font-size: 18px; color: #666; margin-bottom: 10px; font-weight: bold;">
🕒 測驗時間:{now}
</div>
<div style="
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: flex-start;
gap: 20px;
border-bottom: 1px dashed #ccc;
padding-bottom: 15px;
margin-bottom: 15px;
width: 100%;">
<div style="flex: 1;">{current_result_1}</div>
<div style="flex: 1;">{current_result_2}</div>
</div>
</div>
"""
# 將新紀錄放在最前面 (置頂)
history_list.insert(0, new_entry)
# 組合所有歷史紀錄,並整體縮小 80%
# 使用 zoom: 0.8 或 transform 達到字體與版面同時縮小的效果
combined_html = f"""
<div style="zoom: 0.8; -moz-transform: scale(0.8); -moz-transform-origin: 0 0;">
{"".join(history_list)}
</div>
"""
return combined_html, history_list
# 定義重新測驗功能
# In[57]:
# 清空函數:回傳與輸入組件數量相同的 None (15個:gen, age, family + 12個問題)
def clear_all():
# 15個輸入(gen, age, family, q1~q12) + 2個即時結果 + 1個歷史面板
return [None] * 15 + ["", ""]
# 排名設定
def make_rank_list(a_score, d_score, s_score):
items = [
("焦慮 (Anxiety)", a_score),
("憂鬱 (Depression)", d_score),
("壓力 (Stress)", s_score),
]
items_sorted = sorted(items, key=lambda x: x[1], reverse=True)
medal = ["🥇", "🥈", "🥉"]
rows = ""
for i, (name, _) in enumerate(items_sorted):
rows += f"""
<div style="display:flex; justify-content:space-between; padding:10px 0; border-bottom:1px solid #eee;">
<div style="font-size:18px;">{medal[i]} {name}</div>
<div style="font-size:18px; color:#666;">第 {i+1} 名</div>
</div>
"""
return f"""
<div style="padding: 20px; background: white; border-radius: 10px; border: 1px solid #ddd;">
<h2 style="color:#313230; margin-top:0; margin-bottom:10px;">各面向排名</h2>
{rows}
</div>
"""
# 定義主要測試功能
# In[58]:
# DASS-42 官方計分
dep_nums = [3,5,10,13,16,17,21,24,26,31,34,37,38,42]
anx_nums = [2,4,7,9,15,19,20,23,25,28,30,36,40,41]
str_nums = [1,6,8,11,12,14,18,22,27,29,32,33,35,39]
def qcols(nums):
return [f"Q{n}A" for n in nums]
def level_dep(score):
# DASS-42 Depression
if score <= 9: return 0
if score <= 13: return 1
if score <= 20: return 2
if score <= 27: return 3
return 4
def level_anx(score):
# DASS-42 Anxiety
if score <= 7: return 0
if score <= 9: return 1
if score <= 14: return 2
if score <= 19: return 3
return 4
def level_str(score):
# DASS-42 Stress
if score <= 14: return 0
if score <= 18: return 1
if score <= 25: return 2
if score <= 33: return 3
return 4
LEVEL_NAME = {0:"正常", 1:"輕度", 2:"中度", 3:"重度", 4:"極重度"}
def overall_severity_v2(d_level, a_level, s_level):
total = d_level + a_level + s_level
if (d_level == 4) or (a_level == 4) or (s_level == 4):
return 2
if total >= 9:
return 2
if (d_level == 3) or (a_level == 3) or (s_level == 3):
return 1
if total <= 5:
return 0
else:
return 1
OVERALL_NAME = {
0:"低度風險",
1:"中度風險",
2:"高度風險"}
OVERALL_COLOR = {
0: "#91cd92", # 綠
1: "#f59e0b", # 橘
2: "#ef4444", # 紅
}
def predict_dass42_full(name, gen, age, family, *answers):
"""
完整版:42題官方計分(0-3)
回傳:只顯示 Overall(v2)(大字置中)+ 右側排名卡(保留)
並寫入 Google Sheet(DASS42_完整版)
"""
inputs = [name, gen, age, family] + list(answers)
if any(v is None or v == "" for v in inputs):
raise gr.Error("⚠️請確保基本資料與 42 題都已填答。")
# 建立 Q1A~Q42A
row = {f"Q{i+1}A": int(answers[i]) for i in range(42)}
# 官方三向度分數
dep_score = sum(row[c] for c in qcols(dep_nums))
anx_score = sum(row[c] for c in qcols(anx_nums))
str_score = sum(row[c] for c in qcols(str_nums))
# 分級
dep_level = level_dep(dep_score)
anx_level = level_anx(anx_score)
str_level = level_str(str_score)
# Overall v2
overall = overall_severity_v2(dep_level, anx_level, str_level)
# 寫入 Google Sheet(42 題)
# answers42 就是 42 題答案本身
save_to_google_sheets_full42(
inputs=[name, gen, age, family],
dep_score=dep_score,
anx_score=anx_score,
str_score=str_score,
overall=overall,
answers42=answers
)
# 顏色 + 顯示文字
color = OVERALL_COLOR.get(overall, "#999999")
text = OVERALL_NAME.get(overall, str(overall))
# 左側大字結果(不含下方說明)
result_html = f"""
<div style="text-align:center; font-family:sans-serif; padding: 40px 0;">
<div style="font-size: 44px; font-weight: 900; color:#313230; margin-bottom: 26px;">
您的預測結果為
</div>
<div style="font-size: 96px; font-weight: 900; color:{color}; line-height: 1;">
{text}
</div>
</div>
"""
# 右邊排名卡
rank_html = make_rank_list(anx_score, dep_score, str_score)
return result_html, rank_html
# 定義預測功能
def predict_risk(gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12):
inputs = [gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12]
if any(v is None or v == "" for v in inputs):
raise gr.Error("⚠️測驗載入有誤:請確保每一題都已填答或查看填答格式是否正確。")
progress = gr.Progress()
progress(0, desc="模型計算中...")
# age 可能是 int / str,都統一轉 int
age = int(age)
# family 可能是 int / str / "15人以上"
if family == "15人以上":
family = 16
else:
family = int(family)
cols = ["gender", "age", "familysize", "Q2A", "Q4A", "Q19A", "Q20A", "Q28A", "Q21A", "Q26A", "Q37A", "Q42A", "Q11A", "Q12A", "Q27A"]
input_df = pd.DataFrame([[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12]], columns=cols)
progress(0.5, desc="正在分析數據...")
time.sleep(0.5)
score = model.predict(input_df)[0]
if score == 0:
label = "低度風險"
color = "#91cd92"
elif score == 1:
label = "中度風險"
color = "#f59e0b"
elif score == 2:
label = "高度風險"
color = "#ef4444"
else:
label = "計算結果有誤,請重新測試。"
color = "#999999"
a_score = (q1 + q2 + q3 + q4 + q5)
d_score = (q6 + q7 + q8 + q9)
s_score = (q10 + q11 + q12)
t_score = a_score + d_score + s_score
result_score = f"""
<div style="text-align: center; font-family: sans-serif;">
<h2 style="color: #313230;">您的預測結果為</h2>
<h1 style="font-size: 60px; color: {color}; margin: 0;">
{label}
</h1>
</div>
"""
label_html = make_rank_list(a_score, d_score, s_score)
save_to_google_sheets(inputs, a_score, d_score, s_score, t_score, score)
progress(1.0, desc="完成")
return result_score, label_html
# In[59]:
# 設定主題色
theme = gr.themes.Default(
primary_hue="amber",
secondary_hue="amber",
).set(
body_background_fill="#fffbeb"
)
# In[60]:
# 線上主題調色器
# gr.themes.builder()
# In[61]:
# 介面編排
#按鈕及面板格式設定
custom_css = """
#my_green_btn {
background-color: #91cd92 !important;
color: white !important;
border: none;
}
#my_green_btn:hover {
background-color: #72a473 !important; /* 滑鼠懸停時變深 */
}
#my_white_btn {
background-color: #ffffff !important;
color: black !important;
border: 1px solid #e4e4e7;
}
#my_white_btn:hover {
background-color: #e4e4e7 !important;
color: black !important; /* 滑鼠懸停時變深 */
}
.my-custom-panel {
background-color: #fffef8 !important;
border: 2px solid #e4e4e7 !important;
padding: 20px;
border-radius: 15px;
}
#history_panel .label-wrap span {
font-weight: bold !important;
}
"""
# UI
age_choices = list(range(1, 100)) # 1~99歲
family_choices = list(range(1, 16)) + ["15人以上"]
with gr.Blocks() as demo:
# Tab1 歷史
history_state = gr.State([])
gr.Markdown("")
gr.HTML("""
<div style="text-align: center; font-family: sans-serif;">
<h2 style="font-size: 32px; color: #313230; margin: 0;">🌿心理健康風險程度測試📝</h2>
</div>
""")
with gr.Tabs():
# =========================================================
# TAB 1:簡易版(12題|模型)
# =========================================================
with gr.TabItem("簡易版 12題"):
gr.HTML("""
<div style="text-align: center; font-family: sans-serif;">
<h2 style="font-size: 18px; color: #313230; margin: 0;">歡迎來到心理健康風險程度測試環境!<br>
本測驗將透過12題問答,替您在5分鐘內簡單計算出潛在的心理健康風險程度。<br>
請輕鬆填答,無須思慮過度,測驗愉快!</h2>
</div>
""")
with gr.Column(variant="panel", elem_classes="my-custom-panel"):
gr.Markdown("## Step 1. 請輸入基本資訊")
with gr.Row():
with gr.Column():
name = gr.Textbox(label="暱稱")
gen = gr.Dropdown(choices=["男", "女", "其他"], label="性別")
with gr.Column():
age = gr.Dropdown(
choices=age_choices,
label="年齡",
value=None
)
family = gr.Dropdown(
choices=family_choices,
label="家庭人數",
value=None
)
gr.Markdown("## Step 2. 請依自身狀態選擇符合的答案")
q1 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q1.我感覺到口乾舌燥。")
q2 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q2.我感到呼吸困難(例如:在沒有體力勞動的情況下,呼吸過度急促或喘不過氣)。")
q3 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q3.在氣溫不高或沒有體力勞動的情況下,我明顯地流汗(例如:手汗)。")
q4 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q4.我無緣無故地感到害怕。")
q5 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q5.我覺得自己接近恐慌發作的邊緣。")
q6 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q6.我覺得生命沒什麼意義/價值。")
q7 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q7.我感到垂頭喪氣、情緒低落。")
q8 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q8.我覺得未來毫無希望。")
q9 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q9.我發現自己很難打起精神主動去做事。")
q10 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q10.我發現自己很容易變得心煩意亂。")
q11 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q11.我覺得自己消耗了大量的神經能量(處於高度緊繃狀態)。")
q12 = gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label="Q12.我發現自己非常易怒(容易焦躁)。")
sub_button = gr.Button("確認送出", elem_id="my_green_btn")
btn_reset = gr.Button("重新測驗", elem_id="my_white_btn")
with gr.Row():
out_html = gr.HTML()
out_label = gr.HTML()
with gr.Accordion("查看歷史紀錄", open=False, elem_id="history_panel"):
history_display = gr.HTML(value="目前尚無測驗紀錄")
sub_button.click(
fn=predict_risk,
inputs=[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12],
outputs=[out_html, out_label],
).then(
fn=update_history,
inputs=[out_html, out_label, history_state],
outputs=[history_display, history_state],
)
btn_reset.click(
fn=lambda: [None]*15 + ["", ""],
inputs=None,
outputs=[gen, age, family, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10, q11, q12, out_html, out_label],
)
gr.Markdown("## 免責聲明")
gr.Markdown("""本測驗結果僅供參考,非屬正規醫療檢驗範疇。
若對於自身狀況有任何疑慮,敬請尋求正規專業醫療協助!♡第四組關心您♡""")
# =========================================================
# TAB 2:完整版(42題|官方計分)
# =========================================================
with gr.TabItem("完整版 42題"):
# Tab2 歷史
full_history_state = gr.State([])
gr.HTML("""
<div style="text-align: center; font-family: sans-serif; margin-bottom: 6px;">
<h2 style="font-size: 18px; color: #313230; margin: 0;">
歡迎來到 DASS-42 完整版心理測驗!<br>
本測驗將依 42 題官方計分規則,計算您的心理狀態並輸出風險程度。<br>
請依過去一週的感受作答,測驗愉快!
</h2>
</div>
""")
gr.Markdown("## Step 1. 請輸入基本資訊")
with gr.Row():
with gr.Column():
full_name = gr.Textbox(label="暱稱")
full_gen = gr.Dropdown(choices=["男", "女", "其他"], label="性別")
with gr.Column():
full_age = gr.Dropdown(
choices=age_choices,
label="年齡",
value=None
)
full_family = gr.Dropdown(
choices=family_choices,
label="家庭人數",
value=None
)
gr.Markdown("## Step 2. DASS-42(0~3)")
dass42_questions = [
"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. 我發覺難以產生動力去做事",
]
full_q_widgets = []
for q_text in dass42_questions:
full_q_widgets.append(
gr.Radio([("從不", 0), ("偶爾", 1), ("經常", 2), ("總是", 3)], label=q_text)
)
full_submit = gr.Button("確認送出(計算完整版分數)", elem_id="my_green_btn")
with gr.Row():
full_out_html = gr.HTML()
full_out_rank = gr.HTML()
with gr.Accordion("查看歷史紀錄(完整版)", open=False, elem_id="history_panel"):
full_history_display = gr.HTML(value="目前尚無測驗紀錄")
full_submit.click(
fn=predict_dass42_full,
inputs=[full_name, full_gen, full_age, full_family] + full_q_widgets,
outputs=[full_out_html, full_out_rank],
).then(
fn=update_history,
inputs=[full_out_html, full_out_rank, full_history_state],
outputs=[full_history_display, full_history_state],
)
gr.Markdown("## 免責聲明")
gr.Markdown("""本測驗結果僅供參考,非屬正規醫療檢驗範疇。
若對於自身狀況有任何疑慮,敬請尋求正規專業醫療協助!♡第四組關心您♡""")
demo.launch(theme=theme, css=custom_css) |