Spaces:
Sleeping
Sleeping
Update ui/layouts.py
Browse files- ui/layouts.py +140 -15
ui/layouts.py
CHANGED
|
@@ -1,27 +1,152 @@
|
|
| 1 |
-
# ui/layouts.py (
|
| 2 |
import gradio as gr
|
|
|
|
|
|
|
| 3 |
|
| 4 |
def create_ui(visit_count_html: str, theme: gr.Theme):
|
| 5 |
"""
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
"""
|
| 8 |
-
with gr.Blocks(theme=theme, title="版面顯示測試") as demo:
|
| 9 |
-
gr.Markdown("# 除錯測試頁面")
|
| 10 |
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
-
|
| 16 |
-
|
|
|
|
|
|
|
| 17 |
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
-
|
| 22 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 23 |
|
| 24 |
-
|
| 25 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 26 |
|
| 27 |
return demo
|
|
|
|
| 1 |
+
# ui/layouts.py (最終完整版)
|
| 2 |
import gradio as gr
|
| 3 |
+
from config import content, data, defaults
|
| 4 |
+
from core import callbacks
|
| 5 |
|
| 6 |
def create_ui(visit_count_html: str, theme: gr.Theme):
|
| 7 |
"""
|
| 8 |
+
Creates and returns the Gradio UI Blocks.
|
| 9 |
+
|
| 10 |
+
Args:
|
| 11 |
+
visit_count_html: The Markdown string to display the visit count.
|
| 12 |
+
theme: The Gradio theme object to apply to the UI.
|
| 13 |
"""
|
|
|
|
|
|
|
| 14 |
|
| 15 |
+
with gr.Blocks(theme=theme, title="地球物理學") as demo:
|
| 16 |
+
# --- 自訂頂部 Header ---
|
| 17 |
+
gr.Markdown(
|
| 18 |
+
"""
|
| 19 |
+
<style>
|
| 20 |
+
.custom-header {
|
| 21 |
+
background: linear-gradient(135deg, #005f73, #0a9396);
|
| 22 |
+
color: #fff;
|
| 23 |
+
padding: 4rem 2rem;
|
| 24 |
+
text-align: center;
|
| 25 |
+
border-radius: 0 0 20px 20px;
|
| 26 |
+
margin-bottom: 2rem;
|
| 27 |
+
box-shadow: 0 8px 15px rgba(0,0,0,0.1);
|
| 28 |
+
}
|
| 29 |
+
.custom-header h1 {
|
| 30 |
+
font-size: 3.5rem;
|
| 31 |
+
font-weight: 700;
|
| 32 |
+
margin-bottom: 0.8rem;
|
| 33 |
+
line-height: 1.2;
|
| 34 |
+
}
|
| 35 |
+
.custom-header p {
|
| 36 |
+
font-size: 1.6rem;
|
| 37 |
+
font-weight: 400;
|
| 38 |
+
opacity: 0.9;
|
| 39 |
+
margin-top: 0;
|
| 40 |
+
}
|
| 41 |
+
@media (max-width: 768px) {
|
| 42 |
+
.custom-header {
|
| 43 |
+
padding: 3rem 1rem;
|
| 44 |
+
border-radius: 0;
|
| 45 |
+
}
|
| 46 |
+
.custom-header h1 {
|
| 47 |
+
font-size: 2.5rem;
|
| 48 |
+
}
|
| 49 |
+
.custom-header p {
|
| 50 |
+
font-size: 1.2rem;
|
| 51 |
+
}
|
| 52 |
+
}
|
| 53 |
+
</style>
|
| 54 |
+
<div class="custom-header">
|
| 55 |
+
<h1>地球物理概論</h1>
|
| 56 |
+
<p>一個探索我們星球內在奧秘的互動式指南</p>
|
| 57 |
+
</div>
|
| 58 |
+
"""
|
| 59 |
+
)
|
| 60 |
+
|
| 61 |
+
# --- 主導覽列 Tab 容器 ---
|
| 62 |
+
with gr.Row(variant="panel", elem_id="main-nav-tabs"):
|
| 63 |
+
with gr.Tabs(selected=0):
|
| 64 |
+
|
| 65 |
+
with gr.TabItem("🎯 課程目標"):
|
| 66 |
+
gr.Markdown(content.course_goals_md)
|
| 67 |
+
|
| 68 |
+
with gr.TabItem("🗓️ 課程進度"):
|
| 69 |
+
gr.Markdown("### 每週課程安排")
|
| 70 |
+
gr.DataFrame(data.schedule_df, wrap=True)
|
| 71 |
+
|
| 72 |
+
with gr.TabItem("💯 成績計算"):
|
| 73 |
+
gr.Markdown(content.grading_policy_md)
|
| 74 |
+
|
| 75 |
+
with gr.TabItem("🚀 互動體驗區 (程式碼實驗室)"):
|
| 76 |
+
gr.Markdown("## 🚀 互動程式碼實驗室")
|
| 77 |
+
gr.Markdown("歡迎來到這裡!直接修改下方的 Python 程式碼,點擊「執行」,即可在右側看到成果。這是學習程式與地球物理最直接的方式!")
|
| 78 |
+
gr.Info("注意:執行環境已受限,僅支援資料視覺化相關操作。請勿嘗試檔案讀寫或網路請求。")
|
| 79 |
+
|
| 80 |
+
with gr.Accordion("🌍 地圖繪製實驗室 (PyGMT/Cartopy 概念)", open=True):
|
| 81 |
+
with gr.Row():
|
| 82 |
+
with gr.Column(scale=2):
|
| 83 |
+
gr.Markdown("### 說明\n這段程式碼使用 `cartopy` 和 `matplotlib` 函式庫來繪製地理地圖。\n\n**您可以試著:**\n1. 修改 `center_lon`, `center_lat` 來改變地圖中心。\n2. 調整 `extent_lon`, `extent_lat` 來縮放地圖。\n3. 將 `coastline_color` 改成 'red' 或其他顏色。\n4. **在 `symbols` 列表中新增或修改字典,來繪製自訂的符號(例如:標示您所在的城市)。**")
|
| 84 |
+
map_code = gr.Code(label="可編輯的 Python 程式碼", value=defaults.DEFAULT_MAP_CODE, language="python", lines=25)
|
| 85 |
+
map_run_button = gr.Button("執行程式碼", variant="primary")
|
| 86 |
+
with gr.Column(scale=3):
|
| 87 |
+
map_plot_output = gr.Plot(label="地圖輸出")
|
| 88 |
+
map_console_output = gr.Textbox(label="執行結果 / 錯誤訊息", lines=8, interactive=False)
|
| 89 |
+
|
| 90 |
+
with gr.Accordion("📈 震波圖繪製實驗室 (ObsPy 概念)", open=False):
|
| 91 |
+
with gr.Row():
|
| 92 |
+
with gr.Column(scale=2):
|
| 93 |
+
gr.Markdown("### 說明\n這段程式碼使用 `numpy` 產生模擬的地震波數據,並用 `matplotlib` 將其視覺化。\n\n**您可以試著:**\n1. 修改 `p_wave_arrival` 和 `s_wave_arrival` 來改變 P/S 波的抵達時間。\n2. 調整 `main_freq` 來改變地震波的頻率���數值越大,波形越密集)。\n3. 將 `decay_rate` 調小,觀察振幅衰減變慢的效果。")
|
| 94 |
+
seismo_code = gr.Code(label="可編輯的 Python 程式碼", value=defaults.DEFAULT_SEISMO_CODE, language="python", lines=25)
|
| 95 |
+
seismo_run_button = gr.Button("執行程式碼", variant="primary")
|
| 96 |
+
with gr.Column(scale=3):
|
| 97 |
+
seismo_plot_output = gr.Plot(label="震波圖輸出")
|
| 98 |
+
seismo_console_output = gr.Textbox(label="執行結果 / 錯誤訊息", lines=8, interactive=False)
|
| 99 |
+
|
| 100 |
+
with gr.TabItem("🤖 AI 課程助教"):
|
| 101 |
+
with gr.Group():
|
| 102 |
+
gr.Markdown("### 🤖 AI 課程助教 (知識庫 & 即時資訊強化版)")
|
| 103 |
+
gr.Markdown("""
|
| 104 |
+
歡迎使用課程 AI 助教!我整合了靜態的課程知識與多種即時資訊來源,您可以隨時向我提問。
|
| 105 |
+
|
| 106 |
+
---
|
| 107 |
+
|
| 108 |
+
#### 📚 **課程知識庫**
|
| 109 |
+
我可以回答關於本課程的各種問題,例如:`「這門課的評分標準是什麼?」`
|
| 110 |
+
|
| 111 |
+
---
|
| 112 |
+
|
| 113 |
+
#### ⚡ **即時資訊查詢**
|
| 114 |
+
我還能幫您查詢最新的動態資訊,試著問我:
|
| 115 |
+
- **📰 今日新聞**:`「今天有什麼重要新聞?」`
|
| 116 |
+
- **🚨 地震報告**:`「最新的 CWA 顯著地震報告」` 或 `「最近全球有哪些大地震?」`
|
| 117 |
+
- **📢 災害預警**:`「現在有地震預警嗎?」`
|
| 118 |
+
|
| 119 |
+
---
|
| 120 |
|
| 121 |
+
#### 🔎 **進階地震查詢**
|
| 122 |
+
您也可以指定日期與規模來查詢全球地震紀錄,請**完全依照以下格式**提問:
|
| 123 |
+
- `查詢 2024-04-01 到 2024-04-07 規模 6.0 以上地震`
|
| 124 |
+
""")
|
| 125 |
|
| 126 |
+
custom_textbox = gr.Textbox(
|
| 127 |
+
placeholder="對課程有什麼問題嗎?或查詢即時資訊...",
|
| 128 |
+
show_label=False,
|
| 129 |
+
container=False,
|
| 130 |
+
)
|
| 131 |
|
| 132 |
+
gr.ChatInterface(
|
| 133 |
+
callbacks.ai_chatbot_with_kb,
|
| 134 |
+
chatbot=gr.Chatbot(height=450, type="messages", avatar_images=(None, "https://www.google.com/images/branding/googlelogo/1x/googlelogo_color_272x92dp.png")),
|
| 135 |
+
title="課程AI助教",
|
| 136 |
+
description="由結構化知識庫與即時工具驅動的問答機器人",
|
| 137 |
+
textbox=custom_textbox,
|
| 138 |
+
)
|
| 139 |
|
| 140 |
+
# --- Connect Buttons to Backend Functions ---
|
| 141 |
+
map_run_button.click(
|
| 142 |
+
fn=lambda code: callbacks.execute_user_code(code, "地圖繪製"),
|
| 143 |
+
inputs=[map_code],
|
| 144 |
+
outputs=[map_plot_output, map_console_output]
|
| 145 |
+
)
|
| 146 |
+
seismo_run_button.click(
|
| 147 |
+
fn=lambda code: callbacks.execute_user_code(code, "震波圖"),
|
| 148 |
+
inputs=[seismo_code],
|
| 149 |
+
outputs=[seismo_plot_output, seismo_console_output]
|
| 150 |
+
)
|
| 151 |
|
| 152 |
return demo
|