Spaces:
Sleeping
Sleeping
Update app.py
Browse files
app.py
CHANGED
|
@@ -4,11 +4,21 @@ import textwrap
|
|
| 4 |
import folium
|
| 5 |
from obspy.clients.fdsn import Client
|
| 6 |
from obspy import UTCDateTime
|
|
|
|
| 7 |
|
| 8 |
# -------------------------------------------------------------------
|
| 9 |
-
# 範例 1 (基礎)
|
|
|
|
| 10 |
# -------------------------------------------------------------------
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
# --- 這是 Level 1 範例的完整程式碼 ---
|
| 13 |
# 試試看:
|
| 14 |
# 1. 在 geo_dict 中新增一個你自己的詞條。
|
|
@@ -17,11 +27,7 @@ TUTORIAL_CODE_BASIC = textwrap.dedent("""
|
|
| 17 |
# 4. 回到 "Live Demo" 分頁看看你的修改!
|
| 18 |
|
| 19 |
# 1. 知識庫 (你的地科字典)
|
| 20 |
-
geo_dict = {
|
| 21 |
-
"板塊構造 (Plate Tectonics)": "地球的岩石圈被分成許多稱為「板塊」的巨大板塊,這些板塊在軟流圈上緩慢移動,彼此碰撞或分離,形成了火山、地震和山脈。",
|
| 22 |
-
"地震波 (Seismic Wave)": "地震時從震源向四面八方傳播的能量波。主要分為 P 波(壓縮波,速度快)和 S 波(剪力波,速度慢),它們是我們研究地球內部的主要工具。",
|
| 23 |
-
"海嘯 (Tsunami)": "由海底地震、火山爆發或山崩引起的巨大海浪。它在深海中傳播速度極快(可達時速 800 公里),但波高很低;當它靠近淺海岸時,速度減慢,波高則急遽增加。"
|
| 24 |
-
}
|
| 25 |
|
| 26 |
# 2. 定義介面函式
|
| 27 |
def get_definition(term):
|
|
@@ -125,7 +131,8 @@ def run_advanced_code(min_mag, days_ago, code_string):
|
|
| 125 |
safe_globals = {
|
| 126 |
"__builtins__": {
|
| 127 |
"print": print, "Exception": Exception, "len": len, "str": str,
|
| 128 |
-
"float": float, "int": int, "list": list, "dict": dict, "range": range
|
|
|
|
| 129 |
},
|
| 130 |
"folium": folium,
|
| 131 |
"Client": Client,
|
|
@@ -352,10 +359,12 @@ with gr.Blocks(css=css, title="地球物理 x Hugging Face 專案展示") as dem
|
|
| 352 |
with gr.Tabs():
|
| 353 |
with gr.TabItem("🚀 Live Demo"):
|
| 354 |
gr.Markdown("在這裡測試你的程式碼!修改「Edit Code」分頁中的內容,按下「套用變更」,然後在這裡查看結果。")
|
|
|
|
|
|
|
|
|
|
| 355 |
dropdown = gr.Dropdown(
|
| 356 |
label="請選擇一個地科名詞",
|
| 357 |
-
#
|
| 358 |
-
choices=list(eval(TUTORIAL_CODE_BASIC.splitlines()[10].split('=')[1].strip()))
|
| 359 |
)
|
| 360 |
output_textbox = gr.Textbox(label="名詞解釋", lines=5, interactive=False)
|
| 361 |
|
|
@@ -379,7 +388,10 @@ with gr.Blocks(css=css, title="地球物理 x Hugging Face 專案展示") as dem
|
|
| 379 |
# 並動態更新 Dropdown 的選項
|
| 380 |
local_scope = {}
|
| 381 |
try:
|
| 382 |
-
|
|
|
|
|
|
|
|
|
|
| 383 |
new_dict = local_scope.get("geo_dict")
|
| 384 |
if not isinstance(new_dict, dict):
|
| 385 |
raise ValueError("找不到 `geo_dict` 變數或其不是一個字典。")
|
|
@@ -388,7 +400,7 @@ with gr.Blocks(css=css, title="地球物理 x Hugging Face 專案展示") as dem
|
|
| 388 |
new_choices = list(new_dict.keys())
|
| 389 |
return {
|
| 390 |
basic_code_state: new_code, # 儲存新程式碼到 state
|
| 391 |
-
dropdown: gr.Dropdown(choices=new_choices), # 更新 Dropdown
|
| 392 |
apply_msg_basic: gr.Markdown("✅ 變更已套用!請回到 'Live Demo' 分頁查看。")
|
| 393 |
}
|
| 394 |
except Exception as e:
|
|
@@ -490,7 +502,10 @@ with gr.Blocks(css=css, title="地球物理 x Hugging Face 專案展示") as dem
|
|
| 490 |
)
|
| 491 |
gr.Code(
|
| 492 |
label="app.py (Level 1 範例)",
|
| 493 |
-
value=TUTORIAL_CODE_BASIC.replace(
|
|
|
|
|
|
|
|
|
|
| 494 |
language="python",
|
| 495 |
interactive=False
|
| 496 |
)
|
|
@@ -512,14 +527,7 @@ with gr.Blocks(css=css, title="地球物理 x Hugging Face 專案展示") as dem
|
|
| 512 |
gr.Markdown("<h4>2. <code>app.py</code></h4><p>建立 `app.py` 檔案並貼上下面的內容。</p>")
|
| 513 |
gr.Code(
|
| 514 |
label="app.py (Level 2 範例)",
|
| 515 |
-
value=
|
| 516 |
-
"""# --- 匯入函式庫 ---
|
| 517 |
-
import gradio as gr
|
| 518 |
-
import folium
|
| 519 |
-
from obspy.clients.fdsn import Client
|
| 520 |
-
from obspy import UTCDateTime
|
| 521 |
-
|
| 522 |
-
# 1. 定義核心函式"""), # 補上 import
|
| 523 |
language="python",
|
| 524 |
interactive=False
|
| 525 |
)
|
|
|
|
| 4 |
import folium
|
| 5 |
from obspy.clients.fdsn import Client
|
| 6 |
from obspy import UTCDateTime
|
| 7 |
+
import ast # [新增] 用於安全地解析字典
|
| 8 |
|
| 9 |
# -------------------------------------------------------------------
|
| 10 |
+
# 範例 1 (基礎) 的預設資料
|
| 11 |
+
# [修復] 將字典定義為一個變數,以避免解析錯誤
|
| 12 |
# -------------------------------------------------------------------
|
| 13 |
+
TUTORIAL_BASIC_INITIAL_DICT = {
|
| 14 |
+
"板塊構造 (Plate Tectonics)": "地球的岩石圈被分成許多稱為「板塊」的巨大板塊,這些板塊在軟流圈上緩慢移動,彼此碰撞或分離,形成了火山、地震和山脈。",
|
| 15 |
+
"地震波 (Seismic Wave)": "地震時從震源向四面八方傳播的能量波。主要分為 P 波(壓縮波,速度快)和 S 波(剪力波,速度慢),它們是我們研究地球內部的主要工具。",
|
| 16 |
+
"海嘯 (Tsunami)": "由海底地震、火山爆發或山崩引起的巨大海浪。它在深海中傳播速度極快(可達時速 800 公里),但波高很低;當它靠近淺海岸時,速度減慢,波高則急遽增加。"
|
| 17 |
+
}
|
| 18 |
+
|
| 19 |
+
# [修復] 使用 f-string 將字典注入教學程式碼中
|
| 20 |
+
# 我們使用 repr() 來確保字串是有效的 Python 格式
|
| 21 |
+
TUTORIAL_CODE_BASIC = textwrap.dedent(f"""
|
| 22 |
# --- 這是 Level 1 範例的完整程式碼 ---
|
| 23 |
# 試試看:
|
| 24 |
# 1. 在 geo_dict 中新增一個你自己的詞條。
|
|
|
|
| 27 |
# 4. 回到 "Live Demo" 分頁看看你的修改!
|
| 28 |
|
| 29 |
# 1. 知識庫 (你的地科字典)
|
| 30 |
+
geo_dict = {TUTORIAL_BASIC_INITIAL_DICT!r}
|
|
|
|
|
|
|
|
|
|
|
|
|
| 31 |
|
| 32 |
# 2. 定義介面函式
|
| 33 |
def get_definition(term):
|
|
|
|
| 131 |
safe_globals = {
|
| 132 |
"__builtins__": {
|
| 133 |
"print": print, "Exception": Exception, "len": len, "str": str,
|
| 134 |
+
"float": float, "int": int, "list": list, "dict": dict, "range": range,
|
| 135 |
+
"True": True, "False": False, "None": None
|
| 136 |
},
|
| 137 |
"folium": folium,
|
| 138 |
"Client": Client,
|
|
|
|
| 359 |
with gr.Tabs():
|
| 360 |
with gr.TabItem("🚀 Live Demo"):
|
| 361 |
gr.Markdown("在這裡測試你的程式碼!修改「Edit Code」分頁中的內容,按下「套用變更」,然後在這裡查看結果。")
|
| 362 |
+
|
| 363 |
+
# [***** 修復 *****]
|
| 364 |
+
# 更改了 choices 的來源,不再使用 eval(splitlines())
|
| 365 |
dropdown = gr.Dropdown(
|
| 366 |
label="請選擇一個地科名詞",
|
| 367 |
+
choices=list(TUTORIAL_BASIC_INITIAL_DICT.keys()) # <-- 錯誤已修正
|
|
|
|
| 368 |
)
|
| 369 |
output_textbox = gr.Textbox(label="名詞解釋", lines=5, interactive=False)
|
| 370 |
|
|
|
|
| 388 |
# 並動態更新 Dropdown 的選項
|
| 389 |
local_scope = {}
|
| 390 |
try:
|
| 391 |
+
# [修復] 使用 ast.parse 來檢查語法,然後用 exec 執行
|
| 392 |
+
parsed_code = ast.parse(new_code)
|
| 393 |
+
exec(compile(parsed_code, "<string>", "exec"), {"__builtins__": {}}, local_scope)
|
| 394 |
+
|
| 395 |
new_dict = local_scope.get("geo_dict")
|
| 396 |
if not isinstance(new_dict, dict):
|
| 397 |
raise ValueError("找不到 `geo_dict` 變數或其不是一個字典。")
|
|
|
|
| 400 |
new_choices = list(new_dict.keys())
|
| 401 |
return {
|
| 402 |
basic_code_state: new_code, # 儲存新程式碼到 state
|
| 403 |
+
dropdown: gr.Dropdown(choices=new_choices, label="請選擇一個地科名詞"), # 更新 Dropdown
|
| 404 |
apply_msg_basic: gr.Markdown("✅ 變更已套用!請回到 'Live Demo' 分頁查看。")
|
| 405 |
}
|
| 406 |
except Exception as e:
|
|
|
|
| 502 |
)
|
| 503 |
gr.Code(
|
| 504 |
label="app.py (Level 1 範例)",
|
| 505 |
+
value=TUTORIAL_CODE_BASIC.replace(
|
| 506 |
+
"def get_definition(term):",
|
| 507 |
+
"import gradio as gr\n\ndef get_definition(term):\n global geo_dict"
|
| 508 |
+
) + "\n\ndemo.launch()", # 補上 import 和 launch
|
| 509 |
language="python",
|
| 510 |
interactive=False
|
| 511 |
)
|
|
|
|
| 527 |
gr.Markdown("<h4>2. <code>app.py</code></h4><p>建立 `app.py` 檔案並貼上下面的內容。</p>")
|
| 528 |
gr.Code(
|
| 529 |
label="app.py (Level 2 範例)",
|
| 530 |
+
value="# --- 匯入函式庫 ---\nimport gradio as gr\nimport folium\nfrom obspy.clients.fdsn import Client\nfrom obspy import UTCDateTime\n\n" + TUTORIAL_CODE_ADVANCED + "\n\ndemo.launch()", # 補上 import 和 launch
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 531 |
language="python",
|
| 532 |
interactive=False
|
| 533 |
)
|