Spaces:
Sleeping
Sleeping
Download app.py from devorah-ai-2016/HomeBathingService: direct link, hf CLI and curl.
- Browser
- Download file 26.7 kB
-
https://huggingface.co/spaces/devorah-ai-2016/HomeBathingService/resolve/main/app.py
- Command line
-
hf download hf://spaces/devorah-ai-2016/HomeBathingService/app.py
-
curl -L -o app.py https://huggingface.co/spaces/devorah-ai-2016/HomeBathingService/resolve/main/app.py
26.7 kB
| import streamlit as st | |
| from openpyxl import Workbook | |
| from openpyxl.styles import Font, Alignment, Border, Side, PatternFill | |
| from openpyxl.utils import get_column_letter | |
| from io import BytesIO | |
| from datetime import date, time | |
| import sqlite3 | |
| import random | |
| st.set_page_config(page_title="λ°©λ¬Έλͺ©μ μκΈμ μλ΄μΌμ§ μλμμ±κΈ°", layout="wide") | |
| st.title("π λ°©λ¬Έλͺ©μ μκΈμ μλ΄μΌμ§ μλμμ±κΈ° v2") | |
| st.caption("μλ΄μμ β λ¬Έμ μν© β μμΈ β μ‘°μΉ β κΈμ¬λ°μ β λλ€ ν νλ¦Ώ κΈ°λ° μμ λ€μ΄λ‘λ") | |
| st.warning("β οΈ **β» λ³Έ μμ±κΈ°λ ν루 2ν μ΄μ© νλ μ νμ΄ μμ΅λλ€.**") | |
| DB_FILE = "usage.db" | |
| def init_db(): | |
| conn = sqlite3.connect(DB_FILE) | |
| cursor = conn.cursor() | |
| cursor.execute(""" | |
| CREATE TABLE IF NOT EXISTS usage_limit ( | |
| institution TEXT, | |
| user_id TEXT, | |
| use_date TEXT, | |
| count INTEGER, | |
| PRIMARY KEY (institution, user_id, use_date) | |
| ) | |
| """) | |
| conn.commit() | |
| conn.close() | |
| def get_today_usage(institution, user_id): | |
| if not institution or not user_id: | |
| return 0 | |
| init_db() | |
| today_str = date.today().isoformat() | |
| conn = sqlite3.connect(DB_FILE) | |
| cursor = conn.cursor() | |
| cursor.execute( | |
| "SELECT count FROM usage_limit WHERE institution = ? AND user_id = ? AND use_date = ?", | |
| (institution.strip(), user_id.strip(), today_str) | |
| ) | |
| row = cursor.fetchone() | |
| conn.close() | |
| return row[0] if row else 0 | |
| def increase_today_usage(institution, user_id): | |
| if not institution or not user_id: | |
| return | |
| init_db() | |
| today_str = date.today().isoformat() | |
| conn = sqlite3.connect(DB_FILE) | |
| cursor = conn.cursor() | |
| cursor.execute( | |
| "SELECT count FROM usage_limit WHERE institution = ? AND user_id = ? AND use_date = ?", | |
| (institution.strip(), user_id.strip(), today_str) | |
| ) | |
| row = cursor.fetchone() | |
| if row: | |
| cursor.execute( | |
| "UPDATE usage_limit SET count = count + 1 WHERE institution = ? AND user_id = ? AND use_date = ?", | |
| (institution.strip(), user_id.strip(), today_str) | |
| ) | |
| else: | |
| cursor.execute( | |
| "INSERT INTO usage_limit (institution, user_id, use_date, count) VALUES (?, ?, ?, 1)", | |
| (institution.strip(), user_id.strip(), today_str) | |
| ) | |
| conn.commit() | |
| conn.close() | |
| if "generated_data" not in st.session_state: | |
| st.session_state.generated_data = None | |
| inst_val = st.session_state.get("institution", "").strip() | |
| user_val = st.session_state.get("user_id", "").strip() | |
| today_count = get_today_usage(inst_val, user_val) | |
| # Sidebar Usage Panel | |
| st.sidebar.markdown("### π μ¬μ© νλ κ΄λ¦¬") | |
| if not inst_val or not user_val: | |
| st.sidebar.warning("β οΈ κΈ°κ΄λͺ κ³Ό μ¬μ©μ μλ³κ°μ μ λ ₯ν΄μ£ΌμΈμ.") | |
| else: | |
| st.sidebar.write(f"μ€λ μμ± νμ: **{today_count} / 2ν**") | |
| if today_count >= 2: | |
| st.sidebar.error("β μμ± νλ μ΄κ³Ό (2/2)") | |
| else: | |
| st.sidebar.success(f"β μμ± κ°λ₯ (λ¨μ νμ: {2 - today_count}ν)") | |
| REQUIRED_ITEMS = [ | |
| "μκΈμ μ±λͺ ", "μλ μμΌ", "μ±λ³", "μ₯κΈ°μμ λ±κΈ", "κ³μ½μΌ/μμμΌ", "λ³ΈμΈλΆλ΄λ₯ ", | |
| "μλ΄ μΌμ", "μλ΄ κ΅¬λΆ", "μλ΄ μ₯μ", "μλ΄ λ°©λ²", "μλ΄ λμμ μ±λͺ ", "μλ΄μμμ κ΄κ³", | |
| "κΈ°κ΄ λ΄λΉμ μ§μ± λ° μ±λͺ ", "λμμ", "μλ΄ λͺ©μ λ° μ¬μ ", | |
| "μ 체 κΈ°λ₯ μν λ³ν λ° λμ μν", "μΈμ§ κΈ°λ₯ λ° μ¬λ¦¬ μν", "νΌλΆ μν λ° μμ μν", | |
| "λͺ©μ μ°¨λ/μ₯λΉ μμ μν", "보νΈμμ μμ² μ¬ν", | |
| "κΈ°κ΄μ μ€λͺ λ° μλ΄ μ¬ν", "λ¬Έμ ν΄κ²° λλ μ 곡λ μ 보 λ΄μ©", "ν₯ν κΈμ¬ μ 곡 κ³ν", | |
| "κΈμ¬ λ°μ μ¬λΆ", "μ¬ν μ‘°μΉ λ° λͺ¨λν°λ§ κ³ν", "보νΈμ μ λ¬/곡μ§μ¬ν", | |
| "μλ΄μ μλͺ ", "λμμ λλ 보νΈμ μλͺ " | |
| ] | |
| # κ³΅λ¨ νκ°μ§νλ₯Ό λ°μνμ¬ μμ /μ₯λΉ λ° λ§μ‘±λ μμ μΆκ° | |
| AREA_DATA = { | |
| "λͺ©μ κ±°λΆ/νμ‘°λ": { | |
| "problems": ["λͺ©μ κ±°λΆ", "νμ κ±°λΆ", "λ¬Όμ λν 곡ν¬μ¬", "νΌλΆ μ μ΄ μλ―Ό", "νΌλ‘κ° νΈμ", "μ€μκΈ° μ리μ λΆμ"], | |
| "causes": ["μΉλ§€λ‘ μΈν μΈμ§ μ ν", "μΆμμ λ―Όκ°ν¨", "κ³Όκ±° λΆμ μ κ²½ν", "μ 체 λ ΈμΆ μμΉμ¬", "νΌλΆ 건쑰 λ° κ°λ €μ", "λΉμΌ 컨λμ μ ν"], | |
| "actions": ["λ°λ»ν μ€λ΄ μ¨λ(24~26λ) μ μ§", "μΆ©λΆν μ§μ§μ λν λ° λΌν¬ νμ±", "νμλ‘ λͺΈμ κ°μΌ μ± μμ κ° μ 곡", "μ νΈνλ μμ /νκ²½ μ‘°μ±", "κ°νΈμ¬ λ° λ³΄νΈμ νΉμ΄μ¬ν 곡μ "], | |
| }, | |
| "νΌλΆ μν/λ°μ /μμ²": { | |
| "problems": ["νΌλΆ 건쑰 μ¬ν", "λλΆ/미골 λ°μ ", "κ°λ €μμ¦(μμμ¦) νΈμ", "νΌλΆ μ§λ¬΄λ¦/λ°±μ ", "λ―ΈμΈ μ°°κ³Όμ λ°κ²¬", "κ°μ§ μ¬ν"], | |
| "causes": ["νμ‘ μν μ ν", "μ₯μκ° μμ/μ’μ μν", "κΈ°μ κ· μ₯κΈ° μ°©μ©μΌλ‘ μΈν μ΅κΈ°", "μλΆ μμ·¨ λΆμ‘±", "λ Ένλ‘ μΈν νΌλΆ μ₯λ²½ μ½ν"], | |
| "actions": ["λͺ©μ μ§ν 보μ΅μ μΆ©λΆν λν¬", "λ§μ°° λ°©μ§ λ° κ°λ²Όμ΄ λ§μ¬μ§ μ 곡", "νΌλΆ μν μ μ¬ν κ΄μ°° λ° κΈμ¬μ 곡기λ‘μ§ κΈ°μ¬", "κ°νΈμ¬/보νΈμ μ¦κ° λ³΄κ³ ", "κΈ°μ κ· κ΅μ²΄ μ£ΌκΈ° λ¨μΆ μλ΄"], | |
| }, | |
| "체μ¨/λ°μ΄ν λ³ν": { | |
| "problems": ["λͺ©μ μ ν νμ μμΉ/μ ν", "λͺ©μ ν νκΈ°/μ€ν νΈμ", "λ―Έμ΄ λ°μ", "κΈ°λ¦½μ± μ΄μ§λ¬μ νΈμ", "κΈκ²©ν νΌλ‘κ°"], | |
| "causes": ["μ€λ΄μΈ(μμ€) μ¨λμ°¨", "λͺ©μ μ€ μλΆ μμ€", "체λ ₯ μλͺ¨ κ³Όλ€", "κ³Όλν μ¨μ μκ·Ή", "κΈ°μ μ§ν(κ³ νμ/λΉλ¨ λ±) μν₯"], | |
| "actions": ["λͺ©μ μκ° λ¨μΆ(20~30λΆ μ΄λ΄λ‘ μ‘°μ )", "λͺ©μ μ ν λ°λ»ν μλΆ μμ·¨ μ 곡", "μλΉμ€ μ ν 체μ¨/νμ λ± λ°μ΄ν μμ μΈ‘μ ", "κ°νΈμ¬ λ³΄κ³ λ° μκΈμ‘°μΉ μ²΄κ³ λκΈ°", "보νΈμμκ² ν΄μ κΆκ³ μλ΄"], | |
| }, | |
| "λμ/μ΄λ λΆμμ ": { | |
| "problems": ["λ―Έλλ¬μ΄ λ°λ₯μμ 보ν μν", "μμ‘° μΆμ μ κ· ν μμ€", "λΆμΆ μ΄λ μ μ²΄μ€ μ λ¦Ό", "ν μ²΄μ΄ μ΄λ/νΈλμ€νΌ μ λΆμμ ", "기립 μ λ€λ¦¬ ν νλ¦Ό"], | |
| "causes": ["νμ§ κ·Όλ ₯ μ ν λ° νΈλ§λΉ", "λ°λ₯ λ¬ΌκΈ° λ° λΉλλ¬Ό μλ₯", "μΈμ§ κΈ°λ₯ μ νλ‘ μΈν μ§μ λΆμ΄ν", "μ΄λ 보쑰기ꡬ λ―ΈλΉ λ° κ³΅κ° νμ"], | |
| "actions": ["λ―ΈλλΌ λ°©μ§ λ§€νΈ/μ€ν°μ»€ νμ μ¬μ©", "μμ€ λ΄ μμ μμ‘μ΄ μμΉ νμ λ° λ³΄μ‘°", "λͺ©μ μμ μμ μ¬μ© μμΉ μ€μ", "μ΄λ/μ΄μΉ μ 2μΈ 1μ‘° νμ‘° μ²΄κ³ κ°ν", "μκΈμ λ° λ³΄νΈμ λμ λμ μλ°© μμΉ μ¬κ΅μ‘"], | |
| }, | |
| "μμ/μΌλ° 건κ°μν": { | |
| "problems": ["λνΌ κ°μ§/λΉλ¬ μ¬ν", "μλ°ν± μμ κ΄λ¦¬ νμ", "λ°°μ€λ¬Ό μ€μΌ λ°©μΉ", "κ΅¬κ° μμ λΆλ", "체취/μμ°½ λμ μ¬ν"], | |
| "causes": ["κ°μΈμμ μκ° κ΄λ¦¬ λ₯λ ₯ μμ€", "μΈμ§ μ νλ‘ μΈν μμ μΌμ΄ κ±°λΆ", "κ΄μ κ΅¬μΆ λ± μ 체 λμ λ²μ μ ν"], | |
| "actions": ["λνΌ μ μ© μ΄νΈλ‘ μ§μ€ μΈμ ", "λͺ©μ ν μλ°ν± μμ νκ² μ 리", "λ°°μ€λ¬Ό μ€μΌ λΆμ λΆλΆ μΈμ κ°μ΄λ μ μ©", "보νΈμμκ² κ΅¬κ° μΌμ΄ λ³ν κΆκ³ ", "μ²κ²° μ©ν μ νΈλ μ‘°μ¬ λ° λ°μ"], | |
| }, | |
| "νκ²½/μ°¨λ/μ₯λΉ μμ ": { | |
| "problems": ["λͺ©μ μ°¨λ λ΄ μ¨λ μ‘°μ λ―Έν‘", "리ννΈ νμΉ μ κ·Ήλ λΆμκ°", "μ°¨λ λ΄ μμ μ½ν¨/μ¨μ λΆμ‘±", "μ΄λμ μμ‘° μμ μν μ°λ €"], | |
| "causes": ["λμ κΈ° κΈ°μ¨ κΈκ°ν", "κΈ°κ³ μλ μμμ λν 곡ν¬", "μ°¨λ λ Ένν λ° μ κ² μ§μ°", "보νΈμμ κ°μΌ/μμ λ―Όκ°λ μ¦κ°"], | |
| "actions": ["μ°¨λ λ°©λ¬Έ μ νν°/μ¨μ μ¬μ κ°λ", "리ννΈ μ΄μ© μ λ°μ°©νμ¬ μμ¬ μν€κΈ°", "μ κΈ°μ μΈ μ°¨λ/μ₯λΉ μ μ§λ³΄μ μ κ²", "보νΈμμκ² λͺ©μμ‘° μλ μΌμ§ νμΈ λ° μ² μ ν μλ μλ΄"], | |
| }, | |
| "μλΉμ€ λ§μ‘±λ λ° μꡬμ¬ν": { | |
| "problems": ["μλΉμ€ μ 곡 μκ° λ³κ²½ μμ²", "νΉμ μμ보νΈμ¬ μ νΈ/κΈ°νΌ", "μμ보νΈμ¬μμ μμ¬μν΅ λΆμ¬", "μλΉμ€ μκ°(μμμκ°) λΆμ‘± νΈμ"], | |
| "causes": ["보νΈμ κ°μΈ μΌμ λ³κ²½", "μκΈμμ μ’ μ¬μ κ° μ±ν₯ μ°¨μ΄", "μκΈμ μ²κ° μ ν/μΉλ§€", "μ€μ¦λλ‘ μΈν μΌμ΄ μκ° μ§μ°"], | |
| "actions": ["μΌν° μΌμ νμΈ ν μ‘°μ¨ κ°λ₯ μ¬λΆ μ¦μ μλ΄", "μμ κ΅μ²΄ λ©΄λ΄ λ° λ΄λΆ νμ μ§ν", "ν° λͺ©μλ¦¬λ‘ μ²μ²ν μ€λͺ νλλ‘ μ’ μ¬μ μ¬κ΅μ‘", "νλ λ΄μμ μ΅λν ν¨μ¨μ μ΄κ³ κΌΌκΌΌν μ§ν μ½μ"], | |
| }, | |
| } | |
| def make_sentence(area, problems, causes, actions, age, grade, mobility, cognition): | |
| problem_text = ", ".join(problems) | |
| cause_text = ", ".join(causes) | |
| action_text = ", ".join(actions) | |
| # 1. μλ΄λ΄μ© (3κ°μ§ λλ€ ν νλ¦Ώ) | |
| consult_templates = [ | |
| f"μκΈμλ λ§ {age}μΈ, μ₯κΈ°μμ {grade}μ΄λ©° νμ¬ μ΄λμνλ '{mobility}', μΈμ§μνλ '{cognition}'μΌλ‘ νμΈλ¨.\n\nλ°©λ¬Έλͺ©μ κΈμ¬μ 곡 κ³Όμ λ° {area} κ΄λ ¨ μ κΈ°/μμ μλ΄μ μ€μν κ²°κ³Ό, μ£Όμ λ¬Έμ μν©μΌλ‘ {problem_text} νΉμ΄μ¬νμ΄ νμΈλ¨. λͺ©μ μλΉμ€ μ§ν μ μκΈμμ νμ¬ μ 체μ κ°λ λ²μμ μΈμ§, μ¬λ¦¬ μνμ λ°λ₯Έ μΈλ°ν κ΄μ°°μ΄ μλ§λ¨.\n\nμλ΄ κ³Όμ μμ μ λ¬Έμ μ μ£Όλ μμΈμΌλ‘ {cause_text} λ±μ΄ μμ©ν κ°λ₯μ±μ 보νΈμ λ° μ’ μ¬μμ 곡μ νμμΌλ©°, μλΉμ€ μ€ κΈκ²©ν 컨λμ μ ν λ°©μ§μ μ€μ μ λκΈ°λ‘ ν¨.", | |
| f"λμμ(λ§ {age}μΈ, μ₯κΈ°μμ {grade}, μ΄λμν: {mobility}, μΈμ§μν: {cognition})μ μ΅κ·Ό λ°©λ¬Έλͺ©μ μλΉμ€ μ΄μ© μ€νμ {area} μμμ λν΄ μ¬μΈ΅ μλ΄μ μ§νν¨.\n\nμ΅κ·Ό κΈμ¬μ 곡 μ€ {problem_text} μμ£Όμ λ¬Έμ μ λ° μκ΅¬κ° μ§μμ μΌλ‘ κ΄μ°°λ¨. μ£Όμ μμΈμΌλ‘λ {cause_text} λ±μ΄ μ§λͺ©λμμΌλ©°, μκΈμμ μμ ν보μ μλΉμ€ μ§ ν₯μμ μν λμ± λ° νκ²½ κ°μ μ΄ νμν μν©μ.", | |
| f"λ³Έ μκΈμ(λ§ {age}μΈ, {grade})λ νμ {mobility} μμ€μ μ 체기λ₯μ 보μ΄λ©° μΈμ§ μνλ {cognition}μ. κΈμΌ {area} κ΄λ ¨νμ¬ μκΈμ/보νΈμμ λ©΄λ΄μ μ§νν κ²°κ³Ό {problem_text} λ±μ μ λ‘μ¬νμ΄ λ°μνκ³ μμ.\n\nμ΄λ {cause_text}μ κΈ°μΈν κ²μΌλ‘ νμ λλ©°, λ°©λ¬Έλͺ©μ μ€ λ°μν μ μλ μμ μ¬κ³ λ κ°μΌ, 체λ ₯ μ νλ₯Ό μλ°©νκΈ° μν΄ λͺ©μ μ ν μΈμ¬ν μν νμ μ΄ νμμ μ." | |
| ] | |
| # 2. μ‘°μΉλ΄μ© (3κ°μ§ λλ€ ν νλ¦Ώ) | |
| action_templates = [ | |
| f"λ°©λ¬Έλͺ©μ μ§ν μ μκΈμμ λΉμΌ μꡬμ 컨λμ μ λ§μΆμ΄ {action_text} λ±μ μ‘°μΉλ₯Ό μ¦μ μ€μ(λλ κ³ν)νκΈ°λ‘ ν¨. λͺ©μ μμ보νΈμ¬ 2μΈμκ² μΈλΆ μ‘°μΉ λ° μμ μμΉμ μ ννμ¬ νκ° κΈ°μ€μ λΆν©νλ μμ ν κΈμ¬ μ κ³΅μ΄ μ΄λ£¨μ΄μ§λλ‘ μ‘°μΉν¨.", | |
| f"ν΄κ²° λ°©μμΌλ‘ {action_text} μ‘°μΉλ₯Ό νμ₯μ μ μ©νκΈ°λ‘ ν¨. λ΄λΉ μμ보νΈμ¬μκ² ν΄λΉ λ΄μ©μ μ λ¬νμ¬ μλΉμ€ μ μ°¨μ λ°μν λ‘ κ΅μ‘νμμΌλ©°, ν₯ν λμ/νΌλΆμ΄μ/κ±°λΆ λ± νΉμ΄μ¬ν μ§μ μ λ°©λ¬Έκ°νΈ λ± ν μ§μκ³Όμ μ°κ³ λ° μ 보 곡μ λ₯Ό κ°ννκΈ°λ‘ ν¨.", | |
| f"μλ΄ κ²°κ³Όμ λ°λΌ {action_text} λ± μκΈμ λ§μΆ€ν μ‘°μΉλ₯Ό μ 곡νκΈ°λ‘ κ²°μ ν¨. μΌν° λ΄ νμλ₯Ό ν΅ν΄ λ³κ²½λ μλΉμ€ μ 곡 μ§μΉ¨μ λͺ©μ μ°¨λ λ° λν μ§μμκ² κ³΅μ§νμμΌλ©°, μ¦κ°μ μΈ νμ₯ μ μ©μ ν΅ν΄ 보νΈμμ λΆμκ°μ ν΄μμν€κ³ μ ν¨." | |
| ] | |
| # 3. κΈμ¬μ 곡 λ°μλ΄μ© (3κ°μ§ λλ€ ν νλ¦Ώ) | |
| reflection_templates = [ | |
| "μλ΄μ ν΅ν΄ νμΈλ μꡬμ¬ν λ° μ‘°μΉ κ³νμ μ₯κΈ°μμ κΈμ¬μ 곡 κ³Όμ μ μ κ·Ή λ°μν¨. μ¦κ° λ°μ κ°λ₯ν μΈλΆ μ¬νμ λ€μ λ°©λ¬Έλͺ©μ μΌμ λΆν° λ°λ‘ μ μ©νλ©°, νμμ μ₯κΈ°μμκΈ°κ΄ νκ° κ³ μ κΈ°μ€μ λ§μΆμ΄ 'κΈμ¬μ 곡κ³νμ' λ³κ²½ λ° λ³΄μμ κ²ν νκΈ°λ‘ ν¨.", | |
| "κΈμΌ νμ λ μκΈμμ μꡬ λ° λ¬Έμ μν©μ λ€μ λ¬ κΈμ¬μ 곡μΌμ λ° μλΉμ€ λ΄μ©μ λ°μν¨. μ’ μ¬μ μΈμμΈκ³ λμ₯μ κΈ°λ‘νμ¬ λͺ©μ μμμ΄ λ³λλλλΌλ μ°μμ μΈ μΌμ΄κ° μ΄λ£¨μ΄μ§ μ μλλ‘ μ‘°μΉν¨.", | |
| "μκΈμμ μμ λ° μμ μ¦μ§μ μν΄ μλ΄ κ²°κ³Όλ₯Ό νν κΈμ¬μ 곡κ³νμ λ°μν¨. μν λ³νκ° λλ ·ν κ²½μ° κΈμ¬μ 곡κ³νμλ₯Ό μ¬μμ±νμ¬ μκΈμ λ° λ³΄νΈμμκ² μ¬κ΅λΆ/λμλ₯Ό μ»μ μμ μ." | |
| ] | |
| # 4. λͺ¨λν°λ§ κ³ν (3κ°μ§ λλ€ ν νλ¦Ώ) | |
| monitoring_templates = [ | |
| "λͺ©μ λ΄λΉ μμ보νΈμ¬μ μλΉμ€ μ 곡 κΈ°λ‘μ§μ νΉμ΄μ¬ν νΌλλ°±μ λ§€μ£Ό κ²ν ν μμ μ. λ€μ μλ΄ μ ν΄λΉ λ¬Έμ μν©μ΄ μΌλ§λ κ²½κ°λμλμ§, μ‘°μΉμ ν¨κ³Όμ±μ μ΄λ νμ§ νκ°νμ¬ μ§μμ μ΄κ³ μΎμ ν λͺ©μ κ΄λ¦¬λ₯Ό μ€μνκΈ°λ‘ ν¨.", | |
| "μ‘°μΉμ¬ν μ μ© ν 1~2μ£Όκ° λ°©λ¬Έλͺ©μ λͺ¨λν°λ§μ μ§μ€μ μΌλ‘ μ€μν¨. μκΈμμ νμ λ³ν, λ°μ΄ν, νΌλΆ μν κ°μ μ¬λΆλ₯Ό μ μ λλ λ°©λ¬Έμ ν΅ν΄ νμΈνκ³ λ³΄νΈμμ μ£ΌκΈ°μ μΌλ‘ μν΅ν κ³νμ.", | |
| "μκΈμμ λͺ©μ ν λ§μ‘±λ λ° μν λ³νλ₯Ό μμ보νΈμ¬λ₯Ό ν΅ν΄ λ§€ν μ λ¬λ°κΈ°λ‘ ν¨. μΆκ°μ μΈ λ¬Έμ λ°μ μ μΌν°μ₯ λ° μ¬ν볡μ§μ¬κ° μ¦κ° κ°μ νμ¬ μμΈμ λΆμνκ³ λμμ μ¬μ립νκΈ°λ‘ ν¨." | |
| ] | |
| return random.choice(consult_templates), random.choice(action_templates), random.choice(reflection_templates), random.choice(monitoring_templates) | |
| def make_excel(data, consult, action, reflection, monitoring, checked_items, missing_items): | |
| wb = Workbook() | |
| ws = wb.active | |
| ws.title = "μκΈμ μλ΄μΌμ§" | |
| thin = Side(style="thin", color="000000") | |
| border = Border(left=thin, right=thin, top=thin, bottom=thin) | |
| header_fill = PatternFill("solid", fgColor="EAF2F8") # Soft blue | |
| for col in range(1, 10): | |
| ws.column_dimensions[get_column_letter(col)].width = 15 | |
| current_row = 1 | |
| ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row, end_column=9) | |
| ws.cell(current_row, 1).value = f"( {data['κΈ°κ΄λͺ ']} ) λ°©λ¬Έλͺ©μ μλ΄μΌμ§" | |
| ws.cell(current_row, 1).font = Font(bold=True, size=20) | |
| ws.cell(current_row, 1).alignment = Alignment(horizontal="center", vertical="center") | |
| ws.row_dimensions[current_row].height = 36 | |
| current_row += 1 | |
| info_rows = [ | |
| ("μκΈμ μ±λͺ ", data["μκΈμ μ±λͺ "], "μλ μμΌ", data["μλ μμΌ"], "μ±λ³", data["μ±λ³"]), | |
| ("λμ΄", f"λ§ {data['λμ΄']}μΈ", "μ₯κΈ°μμλ±κΈ", data["μ₯κΈ°μμ λ±κΈ"], "κ³μ½/μμμΌ", str(data["μμμΌ"])), | |
| ("λ³ΈμΈλΆλ΄λ₯ ", data["λ³ΈμΈλΆλ΄λ₯ "], "μλ΄μΌμ", str(data["μλ΄μΌμ"]), "μλ΄μκ°", str(data["μλ΄μκ°"])), | |
| ("μλ΄κ΅¬λΆ", data["μλ΄κ΅¬λΆ"], "μλ΄μ₯μ", data["μλ΄μ₯μ"], "μλ΄λ°©λ²", data["μλ΄λ°©λ²"]), | |
| ("μλ΄λμμ", data["μλ΄λμμ"], "κ΄κ³", data["κ΄κ³"], "λμμ", data["λμμ"]), | |
| ("λ΄λΉμ", data["λ΄λΉμ"], "μ§μ± ", data["μ§μ± "], "μλ΄μμ", data["μλ΄μμ"]), | |
| ("μ΄λμν", data["μ΄λμν"], "μΈμ§μν", data["μΈμ§μν"], "λͺ©μμ ν", data["λͺ©μμ ν"]), | |
| ] | |
| for row_data in info_rows: | |
| ws.cell(current_row, 1).value = row_data[0] | |
| ws.merge_cells(start_row=current_row, start_column=2, end_row=current_row, end_column=3) | |
| ws.cell(current_row, 2).value = row_data[1] | |
| ws.cell(current_row, 4).value = row_data[2] | |
| ws.merge_cells(start_row=current_row, start_column=5, end_row=current_row, end_column=6) | |
| ws.cell(current_row, 5).value = row_data[3] | |
| ws.cell(current_row, 7).value = row_data[4] | |
| ws.merge_cells(start_row=current_row, start_column=8, end_row=current_row, end_column=9) | |
| ws.cell(current_row, 8).value = row_data[5] | |
| for col in [1, 4, 7]: | |
| ws.cell(current_row, col).fill = header_fill | |
| ws.cell(current_row, col).font = Font(bold=True) | |
| ws.cell(current_row, col).alignment = Alignment(horizontal="center", vertical="center") | |
| current_row += 1 | |
| sections = [ | |
| ("μλ΄ λ΄μ© (μκΈμ μν λ³ν λ° λ¬Έμ μν©/μμΈ λΆμ)", consult, 3), | |
| ("μ‘°μΉ λ΄μ© λ° μ 곡λ μ 보", action, 3), | |
| ("μ₯κΈ°μμ κΈμ¬μ 곡κ³ν λ°μ λ΄μ©", reflection, 3), | |
| ("μ¬ν μ‘°μΉ λ° λͺ¨λν°λ§ κ³ν", monitoring, 3), | |
| ] | |
| for title, text, height in sections: | |
| ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row, end_column=9) | |
| ws.cell(current_row, 1).value = title | |
| ws.cell(current_row, 1).fill = header_fill | |
| ws.cell(current_row, 1).font = Font(bold=True) | |
| ws.cell(current_row, 1).alignment = Alignment(horizontal="center", vertical="center") | |
| current_row += 1 | |
| ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row + height - 1, end_column=9) | |
| ws.cell(current_row, 1).value = text | |
| ws.cell(current_row, 1).alignment = Alignment(horizontal="left", vertical="top", wrap_text=True) | |
| lines = len(text) // 65 + 1 + text.count('\n') if text else 1 | |
| total_height = max(72, lines * 20 + 10) | |
| single_row_height = total_height / height | |
| for r_offset in range(height): | |
| ws.row_dimensions[current_row + r_offset].height = single_row_height | |
| current_row += height | |
| ws.merge_cells(start_row=current_row, start_column=1, end_row=current_row, end_column=3) | |
| ws.merge_cells(start_row=current_row, start_column=4, end_row=current_row, end_column=6) | |
| ws.merge_cells(start_row=current_row, start_column=7, end_row=current_row, end_column=9) | |
| ws.cell(current_row, 1).value = "κΈ°κ΄ λ΄λΉμ μλͺ " | |
| ws.cell(current_row, 4).value = f"{data['λ΄λΉμ']} (μλͺ )" | |
| ws.cell(current_row, 7).value = "λμμ/보νΈμ (μλͺ )" | |
| ws.cell(current_row, 1).fill = header_fill | |
| ws.cell(current_row, 7).fill = header_fill | |
| max_row = current_row | |
| for row in ws.iter_rows(min_row=1, max_row=max_row, min_col=1, max_col=9): | |
| for cell in row: | |
| cell.border = border | |
| cell.alignment = Alignment( | |
| horizontal=cell.alignment.horizontal or "left", | |
| vertical=cell.alignment.vertical or "center", | |
| wrap_text=True | |
| ) | |
| for r in range(1, max_row + 1): | |
| if ws.row_dimensions[r].height is None: | |
| ws.row_dimensions[r].height = 24 | |
| ws.page_setup.paperSize = ws.PAPERSIZE_A4 | |
| ws.page_setup.orientation = "portrait" | |
| ws.page_setup.fitToWidth = 1 | |
| ws.page_setup.fitToHeight = 0 | |
| ws.sheet_properties.pageSetUpPr.fitToPage = True | |
| ws.page_margins.left = 0.3 | |
| ws.page_margins.right = 0.3 | |
| ws.page_margins.top = 0.4 | |
| ws.page_margins.bottom = 0.4 | |
| ws.print_options.horizontalCentered = True | |
| output = BytesIO() | |
| wb.save(output) | |
| output.seek(0) | |
| return output | |
| col1, col2, col3 = st.columns(3) | |
| with col1: | |
| facility = st.text_input("κΈ°κ΄λͺ ", value="BeeCare μ¬κ°λ³΅μ§μΌν°", key="institution") | |
| user_id = st.text_input("μ¬μ©μ μλ³κ° (μ: ν΄λν°λ²νΈ λ·μ리 λ±)", value="", key="user_id", help="ν루 2ν μ ν κ΄λ¦¬λ₯Ό μν΄ μ¬μ©λ©λλ€.") | |
| name = st.text_input("μκΈμ μ±λͺ ", "μ΄κΈΈμ") | |
| birth = st.text_input("μλ μμΌ", "1945-05-15") | |
| gender = st.selectbox("μ±λ³", ["μ¬", "λ¨"]) | |
| age = st.number_input("λμ΄", min_value=60, max_value=110, value=81) | |
| with col2: | |
| grade = st.selectbox("μ₯κΈ°μμ λ±κΈ", ["1λ±κΈ", "2λ±κΈ", "3λ±κΈ", "4λ±κΈ", "5λ±κΈ", "μΈμ§μ§μλ±κΈ"]) | |
| admission_date = st.date_input("κ³μ½μΌ/μμμΌ", date.today()) | |
| copay = st.selectbox("λ³ΈμΈλΆλ΄λ₯ ", ["15%", "0%", "6%", "9%", "12%", "20%"]) | |
| consult_date = st.date_input("μλ΄μΌμ", date.today()) | |
| with col3: | |
| consult_time = st.time_input("μλ΄μκ°", time(14, 0)) | |
| consult_type = st.selectbox("μλ΄ κ΅¬λΆ", ["μ κΈ° μλ΄", "μμ μλ΄", "μ κ· κ³μ½ μλ΄", "보νΈμ μμ² μλ΄", "λΆλ§ μ²λ¦¬ μλ΄"]) | |
| place = st.selectbox("μλ΄ μ₯μ", ["μκΈμ μν", "μΌν° μ¬λ¬΄μ€", "μ μ μλ΄", "κΈ°ν"]) | |
| method = st.selectbox("μλ΄ λ°©λ²", ["λλ©΄ λ©΄λ΄", "μ μ /μ ν μλ΄", "보νΈμ μ± μλ¦Όμ₯", "κΈ°ν"]) | |
| target = st.text_input("μλ΄ λμμ μ±λͺ ", "μλ ") | |
| col4, col5, col6 = st.columns(3) | |
| with col4: | |
| relation = st.selectbox("μλ΄μμμ κ΄κ³", ["λΈ", "μλ€", "λ³ΈμΈ", "λ°°μ°μ", "λ©°λ리", "μ¬μ", "κΈ°ν 보νΈμ"]) | |
| staff_position = st.selectbox("κΈ°κ΄ λ΄λΉμ μ§μ± ", ["μ¬ν볡μ§μ¬", "λ°©λ¬Έκ°νΈμ¬", "μμ보νΈμ¬", "μμ€μ₯"]) | |
| staff_name = st.text_input("κΈ°κ΄ λ΄λΉμ μ±λͺ ", "μ¬ν볡μ§μ¬") | |
| with col5: | |
| companion = st.text_input("λμμ", "μμ") | |
| mobility = st.selectbox("μ΄λμν", ["λΆμΆ νμ", "λ 립보ν", "μ§ν‘μ΄ λ³΄ν", "μ컀 보ν", "ν μ²΄μ΄ μ΄λ", "μμ μν"]) | |
| cognition = st.selectbox("μΈμ§μν", ["κ²½λ μΉλ§€", "μΈμ§ μνΈ", "μ€λ±λ μΉλ§€", "μ€μ¦ μΉλ§€", "μμ¬μν΅ μ΄λ €μ"]) | |
| with col6: | |
| bath_type = st.selectbox("λͺ©μμ ν", ["λ°©λ¬Έλͺ©μ(μ°¨λλ΄)", "λ°©λ¬Έλͺ©μ(κ°μ λ΄μμ‘°)", "κ°μ λ΄μ€μλμ", "κΈ°ν"]) | |
| area = st.selectbox("μλ΄μμ μ ν", list(AREA_DATA.keys())) | |
| st.subheader("λ¬Έμ μν© / μμΈ / μ‘°μΉ μ ν (νκ°μ§ν μ°κ³)") | |
| problems = st.multiselect("λ¬Έμ μν© μ ν", AREA_DATA[area]["problems"], default=AREA_DATA[area]["problems"][:2], key=f"problems_{area}") | |
| causes = st.multiselect("μλ΄νκ² λ μμΈ μ ν", AREA_DATA[area]["causes"], default=AREA_DATA[area]["causes"][:2], key=f"causes_{area}") | |
| actions = st.multiselect("μ‘°μΉλ΄μ© μ ν", AREA_DATA[area]["actions"], default=AREA_DATA[area]["actions"][:2], key=f"actions_{area}") | |
| # --- GENERATION FLOW WITH EXPLICIT LIMIT LIMITATION --- | |
| st.markdown("---") | |
| is_inputs_filled = bool(facility.strip() and user_id.strip()) | |
| today_count = get_today_usage(facility, user_id) if is_inputs_filled else 0 | |
| can_generate = is_inputs_filled and (today_count < 2) | |
| if not is_inputs_filled: | |
| st.warning("β οΈ μμ± κΈ°λ₯μ μ΄μ©νμλ €λ©΄ μλ¨ μ λ ₯μ°½μμ [κΈ°κ΄λͺ ]κ³Ό [μ¬μ©μ μλ³κ°]μ μ νν μ λ ₯ν΄ μ£ΌμΈμ.") | |
| elif today_count >= 2: | |
| st.error("π¨ μ€λ μ¬μ© κ°λ₯ νμ(2ν)λ₯Ό λͺ¨λ μ¬μ©νμ΅λλ€. μλ‘μ΄ λ¬Έμ μμ±μ λΆκ°νλ©°, μλ κΈ°μ‘΄ μμ±λ λ¬Έμμ μμ λ° λ€μ΄λ‘λλ§ κ°λ₯ν©λλ€.") | |
| checked_items = [] | |
| st.subheader("νμ κΈ°μ¬νλͺ© 체ν¬λ¦¬μ€νΈ (κ³΅λ¨ νκ°μ§ν κΈ°μ€)") | |
| for item in REQUIRED_ITEMS: | |
| if st.checkbox(item, value=True, key=f"check_{item}"): | |
| checked_items.append(item) | |
| missing_items = [item for item in REQUIRED_ITEMS if item not in checked_items] | |
| score = int((len(checked_items) / len(REQUIRED_ITEMS)) * 100) | |
| if score == 100: | |
| st.success(f"μλ΄μΌμ§ μμ±λ: {score}μ / λλ½ νλͺ© μμ (νκ°μ§ν μΆ©μ‘±)") | |
| elif score >= 85: | |
| st.warning(f"μλ΄μΌμ§ μμ±λ: {score}μ / μΌλΆ νλͺ© νμΈ νμ") | |
| else: | |
| st.error(f"μλ΄μΌμ§ μμ±λ: {score}μ / νμνλͺ© 보μ νμ") | |
| data = { | |
| "κΈ°κ΄λͺ ": facility, | |
| "μκΈμ μ±λͺ ": name, | |
| "μλ μμΌ": birth, | |
| "μ±λ³": gender, | |
| "λμ΄": age, | |
| "μ₯κΈ°μμ λ±κΈ": grade, | |
| "μμμΌ": admission_date, | |
| "λ³ΈμΈλΆλ΄λ₯ ": copay, | |
| "μλ΄μΌμ": consult_date, | |
| "μλ΄μκ°": consult_time, | |
| "μλ΄κ΅¬λΆ": consult_type, | |
| "μλ΄μ₯μ": place, | |
| "μλ΄λ°©λ²": method, | |
| "μλ΄λμμ": target, | |
| "κ΄κ³": relation, | |
| "λ΄λΉμ": staff_name, | |
| "μ§μ± ": staff_position, | |
| "λμμ": companion, | |
| "μλ΄μμ": area, | |
| "μ΄λμν": mobility, | |
| "μΈμ§μν": cognition, | |
| "λͺ©μμ ν": bath_type, | |
| } | |
| if st.button("π μλ΄μΌμ§ & μμ μμ±νκΈ°", disabled=not can_generate): | |
| if not is_inputs_filled: | |
| st.error("κΈ°κ΄λͺ κ³Ό μ¬μ©μ μλ³κ°μ μ λ ₯ν΄μΌ μμ±ν μ μμ΅λλ€.") | |
| st.stop() | |
| if today_count >= 2: | |
| st.error("μ€λ μ¬μ© κ°λ₯ νμλ₯Ό λͺ¨λ μ¬μ©νμ΅λλ€.") | |
| st.stop() | |
| increase_today_usage(facility, user_id) | |
| gen_consult, gen_action, gen_reflection, gen_monitoring = make_sentence( | |
| area, problems, causes, actions, age, grade, mobility, cognition | |
| ) | |
| st.session_state.generated_data = { | |
| "consult": gen_consult, | |
| "action": gen_action, | |
| "reflection": gen_reflection, | |
| "monitoring": gen_monitoring, | |
| "data": data, | |
| "checked_items": checked_items, | |
| "missing_items": missing_items | |
| } | |
| st.success("π νκ°μ§νμ λ§μΆ μλ΄μΌμ§κ° 무μμ ν νλ¦ΏμΌλ‘ μμ±λμμ΅λλ€! μλμμ λ΄μ©μ νμΈ λ° μμ ν ν μμ νμΌμ λ€μ΄λ‘λνμΈμ.") | |
| st.rerun() | |
| if st.session_state.generated_data is not None: | |
| g_data = st.session_state.generated_data | |
| st.subheader("μλ΄ λ΄μ© (μκΈμ μν λ³ν λ° λ¬Έμ μν©/μμΈ λΆμ)") | |
| ui_consult = st.text_area("μλ΄λ΄μ© μμ κ°λ₯", g_data["consult"], height=220) | |
| st.subheader("μ‘°μΉ λ΄μ© λ° μ 곡λ μ 보") | |
| ui_action = st.text_area("μ‘°μΉλ΄μ© μμ κ°λ₯", g_data["action"], height=180) | |
| st.subheader("μ₯κΈ°μμ κΈμ¬μ 곡κ³ν λ°μ λ΄μ©") | |
| ui_reflection = st.text_area("κΈμ¬μ 곡 λ°μ λ΄μ© μμ κ°λ₯", g_data["reflection"], height=130) | |
| st.subheader("μ¬ν μ‘°μΉ λ° λͺ¨λν°λ§ κ³ν") | |
| ui_monitoring = st.text_area("λͺ¨λν°λ§ κ³ν μμ κ°λ₯", g_data["monitoring"], height=130) | |
| excel_file = make_excel( | |
| g_data["data"], | |
| ui_consult, | |
| ui_action, | |
| ui_reflection, | |
| ui_monitoring, | |
| g_data["checked_items"], | |
| g_data["missing_items"] | |
| ) | |
| st.download_button( | |
| label="π₯ μκΈμ μλ΄μΌμ§ μμ λ€μ΄λ‘λ", | |
| data=excel_file, | |
| file_name=f"{g_data['data']['μκΈμ μ±λͺ ']}_{g_data['data']['μλ΄μμ']}_λ°©λ¬Έλͺ©μμλ΄μΌμ§.xlsx", | |
| mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" | |
| ) |