File size: 4,907 Bytes
e9c6277
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import requests
from bs4 import BeautifulSoup
import pandas as pd
import gradio as gr

def fetch_occupancy_data(hospital_id="10", floor=""):
    """
    爬取奇美醫院佔床率資料
    
    Args:
        hospital_id (str): 醫院ID,默認為"10"(總院)
        floor (str): 樓層篩選,默認為空
        
    Returns:
        tuple: (DataFrame, str) - 佔床資料的DataFrame和狀態訊息
    """
    # URL of the page to scrape
    url = f"https://www.chimei.org.tw/%E4%BD%94%E5%BA%8A%E7%8E%87%E6%9F%A5%E8%A9%A2/%E4%BD%94%E5%BA%8A%E7%8E%87%E6%9F%A5%E8%A9%A2.aspx?ihospital={hospital_id}&ffloor={floor}"
    
    try:
        # Send HTTP request
        response = requests.get(url)
        response.encoding = 'utf-8'  # Set encoding to handle Chinese characters
        
        # Create BeautifulSoup object
        soup = BeautifulSoup(response.text, 'html.parser')
        
        # Find the target table (DG1)
        target_table = soup.find('table', {'id': 'DG1'})
        
        # Extract data from the table
        data = []
        if target_table:
            rows = target_table.find_all('tr')
            
            # Skip the header row
            for row in rows[1:]:
                cols = row.find_all('td')
                if len(cols) == 5:  # Ensure row has 5 columns
                    bed_type = cols[0].text.strip()
                    total_beds = int(cols[1].text.strip())
                    occupied_beds = int(cols[2].text.strip())
                    available_beds = int(cols[3].text.strip())
                    occupancy_rate = cols[4].text.strip()
                    
                    data.append({
                        '病床類別': bed_type,
                        '總床數': total_beds,
                        '佔床數': occupied_beds,
                        '空床數': available_beds,
                        '佔床率': occupancy_rate
                    })
        
        # Create pandas DataFrame
        df = pd.DataFrame(data)
        
        if df.empty:
            return None, "無法獲取資料,請檢查網絡連接或醫院ID。"
        
        return df, "資料獲取成功!"
    
    except Exception as e:
        return None, f"發生錯誤: {str(e)}"

def create_visualization(df):
    """
    建立資料視覺化圖表
    
    Args:
        df (DataFrame): 佔床率資料
        
    Returns:
        matplotlib.figure.Figure: 視覺化圖表
    """
    if df is None or df.empty:
        return None
    
    # 建立佔床率圖表
    fig = df.plot(x='病床類別', y=['佔床數', '空床數'], kind='bar', stacked=True, 
                 figsize=(10, 6), title='奇美醫院各類病床佔用情況').get_figure()
    
    return fig

def process_query(hospital_id, floor):
    """
    處理使用者查詢
    
    Args:
        hospital_id (str): 醫院ID
        floor (str): 樓層篩選
        
    Returns:
        tuple: (DataFrame HTML, 圖表, 訊息)
    """
    df, message = fetch_occupancy_data(hospital_id, floor)
    
    if df is not None:
        fig = create_visualization(df)
        html_table = df.to_html(classes="table table-striped", index=False)
        return html_table, fig, message
    else:
        return None, None, message

# 定義Gradio介面
with gr.Blocks(title="奇美醫院佔床率查詢系統") as app:
    gr.Markdown("# 奇美醫院佔床率查詢系統")
    gr.Markdown("該系統可以即時查詢奇美醫院各類病床的佔用情況")
    
    with gr.Row():
        with gr.Column(scale=1):
            # 輸入欄位
            hospital_id = gr.Dropdown(
                choices=[
                    ("總院", "10"),
                    ("柳營分院", "20"),
                    ("佳里分院", "30"),
                    ("鹽埕分院", "40")
                ],
                value="10",
                label="選擇醫院"
            )
            
            floor = gr.Textbox(label="樓層篩選 (可選)", placeholder="例如:3F、5F")
            
            query_btn = gr.Button("查詢佔床率", variant="primary")
        
        with gr.Column(scale=2):
            # 輸出欄位
            output_message = gr.Textbox(label="查詢狀態")
            output_table = gr.HTML(label="佔床率資料表")
            output_chart = gr.Plot(label="佔床情況視覺化")
    
    # 設定查詢按鈕動作
    query_btn.click(
        fn=process_query,
        inputs=[hospital_id, floor],
        outputs=[output_table, output_chart, output_message]
    )
    
    gr.Markdown("### 使用說明")
    gr.Markdown("""
    1. 從下拉選單選擇要查詢的醫院
    2. 可選擇性地輸入特定樓層進行篩選
    3. 點擊"查詢佔床率"按鈕獲取最新資料
    4. 系統會顯示表格和視覺化圖表
    """)

# 啟動Gradio應用
if __name__ == "__main__":
    app.launch()