Python : Poetry vs. uv

注意:此文章由AI輔助生成

第 1 章:執行摘要

1.1. 現代 Python 工具鏈的困境

在當代 Python 開發實踐中,選擇合適的專案與依賴管理工具,已成為影響團隊生產力、專案穩定性與開發體驗的關鍵決策。這不僅是工具的選擇,更是開發哲學的抉擇。傳統上由 pipvenvsetuptools 等工具組成的分散式工作流程,長期以來因其複雜性、不確定性與效率瓶頸而備受詬病。在此背景下,現代化、整合式的工具應運而生,其中 Poetry 與 uv 作為兩個最具代表性的解決方案,分別代表了兩種不同的演進路徑與核心價值主張。本報告旨在對這兩者進行全面、深入的比較分析,為開發者與技術領導者提供清晰的戰略決策依據。

1.2. Poetry:成熟、整合的專案工作台

Poetry 被視為定義了現代 Python 專案管理標準的成熟工具。它提供了一個全面整合的解決方案,旨在解決傳統工具鏈的碎片化問題。其核心價值在於提供一個統一、具確定性且符合人體工學的開發體驗,將專案初始化、依賴管理、虛擬環境隔離、建構、打包至發布的完整生命週期,整合到一個連貫、具備高度主見的工作流程中 1。Poetry 的出現,標誌著 Python 生態系從一系列零散工具的組合,邁向一個真正一體化的專案管理時代。

1.3. uv:高效能、整合的工具鏈

uv 則是以顛覆者姿態出現的後起之秀,其設計理念植根於極致的執行速度與廣泛的工具鏈整合雄心。由高效能 Rust 語言編寫而成,uv 的目標不僅是成為一個更快的依賴管理器,而是要將 pip(套件安裝)、venv/virtualenv(環境建立)、pyenv(Python 版本管理)及 pipx(工具執行)等多種關鍵開發工具的功能,全部整合到一個單一、高效能的二進位檔案中 3

uv 代表了對 Python 開發基礎設施的重新思考,試圖從根本上解決效能瓶頸與工具過多的問題。

1.4. 核心發現概覽

本報告的深入分析揭示了 Poetry 與 uv 之間幾個關鍵的差異維度:

  • 效能(Performance)uv 在執行速度上實現了世代性的飛躍,其安裝與解析速度比傳統工具快 10 至 100 倍。這不僅是量級上的提升,更是一種質變,它催生了更高效的本地開發與持續整合/持續部署(CI/CD)工作流程 5
  • 範疇與哲學(Scope & Philosophy):兩者最核心的分歧在於哲學。Poetry 提供的是一個「統一的專案工作流程」(Unified Project Workflow),它透過一個結構化、帶有主見的流程引導使用者。相對地,uv 提供的是一個「整合的開發者工具鏈」(Consolidated Developer Toolchain),它提供了一套強大、靈活的基礎元件,旨在取代多個獨立的工具。
  • 成熟度與發展動能(Maturity vs. Momentum):開發者面臨的選擇,是在 Poetry 經過驗證的穩定性、功能完備性與 uv 無與倫比的效能、爆炸性的發展動能之間做出權衡。uv 正在迅速補齊功能上的差距,但其快速的演進也帶來了不同於 Poetry 的穩定性風險 8

1.5. 建議框架總結

最終的選擇取決於團隊的具體優先級。若追求的是專案結構的嚴格一致性、成熟穩定的工作流程以及豐富的專案管理功能,Poethry 依然是極為可靠的選擇。然而,若團隊的首要目標是極致的執行效能、工具鏈的簡化與整合,以及更大的靈活性,uv 則展現出無可匹敵的優勢。本報告的後續章節將提供一個詳細的決策框架,幫助不同需求的團隊做出最適合的戰略選擇。

第 2 章:Python 打包生態的演進:工具的景觀

2.1. 碎片化時代:pipvenvsetup.py

要理解 Poetry 與 uv 的價值,必須回顧它們試圖解決的歷史問題。傳統的 Python 開發工作流程是一個高度碎片化的生態系統,開發者需要在多個獨立工具之間切換,造成了巨大的認知負擔。venvvirtualenv 用於建立隔離的虛擬環境;pip 搭配 requirements.txt 檔案用於管理應用程式的依賴;而對於需要發布的函式庫,則需使用 setup.py 檔案來定義元數據與依賴 2

這種模式存在諸多根本性缺陷。requirements.txt 缺乏標準化的方式來區分直接依賴與傳遞性依賴,導致環境難以精確複製。pip 早期的依賴解析器採用簡單的回溯演算法,在面對複雜的依賴衝突時,常常無法找到解決方案,或導致臭名昭著的「依賴地獄」(Dependency Hell)6。由於缺乏原生的鎖定檔案(lock file)機制,開發者、測試環境與生產環境之間的依賴版本不一致,成為了「在我的機器上可以運作」(works on my machine)問題的主要根源。

2.2. 第一次整合浪潮:Poetry 的崛起

Poetry 的誕生,正是對這種碎片化狀態的直接且成功的反擊。它引領了將多種功能整合為一體化工具的主流趨勢。Poetry 的核心創新在於,它將依賴管理、環境隔離、專案建構與發布等功能,全部整合到一個圍繞 pyproject.toml 標準的、具有高度一致性的命令列介面中 1

透過引入 poetry.lock 檔案,Poetry 確保了依賴安裝的確定性與可重複性,從根本上解決了環境不一致的問題。其直觀的命令(如 poetry addpoetry install)極大地簡化了開發者的日常操作。Poetry 不僅僅是一個工具,它更推廣了一種現代化的 Python 專案管理哲學,強調結構化、可預測性與開發者體驗,成功地解決了傳統工作流程中的諸多痛點。

2.3. 第二次浪潮:對效能與整合的追求

uv 的出現,則代表了 Python 工具生態的下一個演進階段。它的誕生背景,是基於 Ruff 等高效能、以 Rust 編寫的工具在 Python 社群取得的巨大成功 14。如果說 Poetry 解決了「工作流程整合」的問題,那麼

uv 的目標則是解決剩餘的「執行效能」瓶頸與「工具鏈雜亂」的問題。

uv 的雄心遠不止於成為一個更快的 Poetry 替代品。它的設計目標是成為一個全面的工具鏈,不僅取代專案管理器,還要取代諸如 pyenv(Python 版本管理)和 pipx(CLI 工具執行)等周邊工具 5

uv 試圖透過一個單一的、極致快速的二進位檔案,為 Python 開發者提供一個前所未有地簡潔、高效的開發基礎設施。

第 3 章:Poetry:整合的專案與依賴工作台

3.1. 設計哲學:統一、確定性與開發者人體工學

Poetry 的設計理念圍繞三大核心支柱,這些支柱共同塑造了其作為一個全面專案管理工具的特性。

  • 統一性(Unification):Poetry 的首要原則是成為管理 Python 專案生命週期的單一權威工具。它旨在取代開發者需要學習和協調 pipvirtualenvsetuptoolstwine 等多個工具的傳統模式 1。透過提供一個一致的介面,Poetry 建立了一個完整且帶有明確主張的工作流程,涵蓋從專案建立到發布的所有環節 1
  • 確定性(Determinism)poetry.lock 檔案是 Poetry 可靠性的基石。它精確記錄了每個直接依賴及其所有傳遞性依賴的確切版本。這保證了每位開發者、每次 CI 執行以及每個生產部署都使用完全相同的環境,從而根除了因依賴版本不一致而引發的各類棘手問題 1
  • 人體工學(Ergonomics):Poetry 的命令列介面(CLI)經過精心設計,力求直觀易用。其命令直接對應開發者的意圖(例如 addremoveupdatepublish),並提供合理且安全的預設行為 20。這種帶有明確主張的設計,引導使用者遵循一致的最佳實踐工作流程,降低了學習曲線和日常操作的複雜性 21

3.2. 核心工作流程:從 poetry newpoetry publish

Poetry 為 Python 專案的整個生命週期提供了一套流暢且標準化的操作流程。

  • 專案初始化poetry new <project-name> 命令會自動生成一個符合最佳實踐的標準專案結構。這個結構包括一個原始碼目錄(<project_name>/)、一個測試目錄(tests/)、一個 README 檔案,以及作為專案配置核心的 pyproject.toml 檔案 1。對於已存在的專案,可以使用 poetry init 命令,它會啟動一個互動式嚮導來協助建立 pyproject.toml 檔案 23
  • 依賴管理
    • poetry add [package]:這是一個原子性的操作。單一命令即可完成將依賴項新增至 pyproject.toml、對整個依賴圖進行完整解析,以及更新 poetry.lock 檔案以反映最新狀態的多個步驟 1
    • poetry install:此命令優先使用 poetry.lock 檔案。如果鎖定檔案存在,它將精確安裝其中指定的版本,確保確定性的建構。如果鎖定檔案不存在,它會根據 pyproject.toml 中的約束解析依賴,並建立一個新的鎖定檔案 25
    • poetry update:此命令會智慧地將依賴項更新到 pyproject.toml 中版本約束所允許的最新版本,並重新生成鎖定檔案 1
  • 環境互動:Poetry 抽象化了虛擬環境的管理。poetry shell 命令可以在當前的 shell 中啟動專案的虛擬環境,而 poetry run [command] 則可以在該環境中執行命令,無需手動啟動環境 17。Poetry 會自動為每個專案建立和管理這些虛擬環境,通常存放在一個集中的快取目錄中 2
  • 打包與發布:發布流程被簡化為兩個核心命令:poetry build 會建立符合標準的原始碼發行版(sdist)和輪子檔案(wheel),而 poetry publish 則會將這些產物上傳到 PyPI 或設定好的私有儲存庫 2

3.3. 深入功能分析

  • 進階依賴解析器:Poetry 配備了一個精密且詳盡的依賴解析器。它會徹底分析整個依賴樹,以找到一組相容的套件組合。在處理複雜的依賴場景時,它能優雅地應對,並在無法找到解決方案時提供清晰的錯誤訊息,解釋衝突的原因 2
  • 依賴群組(Dependency Groups):這是專業開發流程中的基石功能。它允許開發者在 pyproject.toml 中將依賴項劃分為不同的群組,例如 devtestdocs(使用 [tool.poetry.group.dev.dependencies] 這樣的區段)。這些群組可以被選擇性地安裝(例如,poetry install --with dev,test),這對於保持生產環境的精簡與安全至關重要 1
  • 語意化版本約束:Poetry 積極推廣並簡化了語意化版本控制(Semantic Versioning)的使用。透過直觀的版本約束符號,如脫字符(^)和波浪符(~),開發者可以安全且可預測地管理套件更新。例如,^1.2.3 允許更新到 1.9.9,但不允許更新到 2.0.0 22
  • Python 版本管理(關鍵限制):此處需要強調一個與 uv 的關鍵區別。Poetry 允許開發者透過 pyproject.toml 中的 requires-python 欄位來指定專案支援的 Python 版本。然而,Poetry 本身不會為您安裝 Python 直譯器。開發者必須自行負責確保系統上存在一個相容的 Python 版本 24

3.4. 關於 Poetry 角色與影響的洞察

Poetry 在團隊協作中的最大優勢,不僅在於其豐富的功能,更在於它能夠強制推行一套一致、標準化的工作流程。這個特性源於其設計哲學的自然延伸。首先,Poetry 提供了一個統一的工具鏈,為所有專案生命週期任務(如 new, add, install, run, build, publish)定義了一套一致的命令 1。這為團隊中的所有開發者建立了一種共通的「語言」和共享的心智模型。團隊不再依賴於客製化的

Makefile 目標或零散的 shell 腳本,整個工作流程由標準化、文件齊全的 Poetry 命令來定義。這極大地降低了認知負擔,最大限度地減少了「在我的機器上可以運作」的問題,並顯著縮短了新成員的上手時間。正如研究所指出的,當目標是「從內部強制專案開發方式的一致性」時,Poetry 是更佳的選擇 21

然而,Poetry 這種一體化、帶有明確主張的設計,雖然是其簡潔性的來源,但也內在地造成了專案定義與工具本身的更緊密耦合。Poetry 在 pyproject.toml 中使用其專有的 [tool.poetry] 命名空間來定義專案的元數據、依賴、腳本和建構配置 23。這意味著專案的原始定義是「Poetry 原生」的。雖然它最終會產生標準的 wheel 檔案,但其源頭定義與 Poetry 的特定模式緊密相連。要有效地管理這樣的專案,所有開發者都必須使用 Poetry。因此,將一個專案從 Poetry 遷移到另一個管理器(如 Hatch 或 PDM)是一項不小的任務,需要將這種 Poetry 特定的配置轉換為更基於標準的格式。因此,採用 Poetry 不僅是選擇一個工具,更是一項對其生態系統和特定專案管理方式的戰略承諾。

第 4 章:uv:高效能、整合的工具鏈

4.1. 設計哲學:前所未有的速度、整合與 PEP 合規性

uv 的設計理念由三大支柱構成,這些支柱共同定義了其作為新一代 Python 工具的革命性特質。

  • 對效能的極致追求(Obsessive Focus on Performance)uv 最引人注目且首要的設計原則,是對速度的無情追求。它採用高效能的 Rust 語言從頭打造,並利用現代化的技術,如平行處理、帶有寫入時複製(Copy-on-Write)語意的全域快取,以及一個高度最佳化的解析器,使其速度比 pip 快 10 至 100 倍,並且也明顯快於 Poetry 3。這種效能的提升是如此顯著,以至於它能夠催生全新的、更高效的工作流程 5
  • 工具鏈整合(Toolchain Consolidation)uv 公開宣稱的目標是成為「Python 的 Cargo」7,即一個單一的靜態二進位檔案,整合了眾多分散工具的功能。這包括 pippip-tools(套件管理)、virtualenv(環境建立)、pipx(工具執行),甚至 pyenv(Python 版本安裝)4。這種整合極大地簡化了開發者需要安裝和維護的工具鏈。
  • PEP 合規性與模組化(PEP Compliance and Modularity)uv 的一個關鍵戰略選擇是嚴格遵守現代 Python 增強提案(PEP)來定義專案元數據,它使用如 [project][project.optional-dependencies] 等標準區段 5。這使得專案配置更具可攜性,減少了對 uv 本身的依賴。其設計刻意保持模組化,允許使用者僅將 uv 用於單一任務(例如,作為一個更快的 pip),而無需承諾使用其整個生態系統 7

4.2. 核心工作流程:專案管理與 pip 相容層

uv 提供了兩種主要的工作流程,以適應不同的使用情境和遷移路徑。

  • 專案管理工作流程
    • uv init:建立一個新專案,其 pyproject.toml 檔案使用符合 PEP 標準、與工具無關的區段 4
    • uv add [package]:在一個單一、快速的命令中,完成將依賴項新增至 pyproject.toml、解析依賴圖、更新 uv.lock 檔案,並同步本地環境的多個步驟 4
    • uv sync:這是核心的安裝命令,類似於 poetry install。它能極速地將虛擬環境同步到 uv.lock 檔案中定義的確切狀態,確保環境的確定性 4
    • uv run [command]:在受控的環境中執行命令。其關鍵特性在於,它會在執行前隱式地確保環境已同步,從而消除了開發者因忘記安裝新依賴而導致的一類常見錯誤 8
  • pip 相容性工作流程
    • 這是 uv 採納策略的基石。它提供了一個 uv pip 子命令,可作為常見 pippip-tools 命令的直接、高速替代品 3
    • uv pip install [package]uv pip compile [file.in]uv pip sync [file.txt] 等命令,允許團隊在完全不改變其現有基於 requirements.txt 的工作流程的情況下,享受到 uv 帶來的效能優勢 3

4.3. 差異化能力:超越專案管理

uv 的功能範疇遠遠超出了傳統的專案管理,提供了多項 Poetry 所不具備的整合能力。

  • 整合的 Python 版本管理:這是 uv 相較於 Poetry 的一個主要優勢。uv python install [version] 命令可以下載和管理多個 Python 直譯器版本,而 uv python pin [version] 則可以透過 .python-version 檔案設定專案特定的版本。這完全取代了對 pyenv 等獨立工具的需求 3
  • 整合的工具管理uvx [tool] 命令(uv tool run 的別名)可以在一個臨時、隔離的環境中執行任何 Python 套件提供的命令列工具,這取代了 pipx 的功能。它非常適合用於執行 linter、formatter 或其他開發工具,而不會污染專案或全域環境 3uv tool install 則允許永久性地安裝這些工具。
  • 單一檔案腳本執行uv 支援 PEP 723 標準,使其能夠解析嵌入在單一 Python 腳本頂部註解中的依賴元數據。uv run [script.py] 命令會自動建立一個臨時環境,安裝指定的依賴,並執行該腳本。這對於自動化任務和一次性腳本來說是理想的解決方案 3

4.4. 關於 uv 角色與影響的洞察

uv 的革命性速度和隱式自動化操作,從根本上降低了開發者遵循最佳實踐所需的「活化能」(Activation Energy)。傳統的開發流程包含一系列離散的手動步驟:建立虛擬環境、啟動它、安裝依賴、執行程式碼,並在程式碼變更時記得更新依賴。每一步都需要刻意的努力和時間。uv 的工作流程則整合了這些步驟。像 uv run my_script.py 這樣一個單一命令,可以自動且幾乎瞬間地處理 Python 版本檢查、虛擬環境建立、依賴同步和程式碼執行 16。由於維護一個正確、同步的環境所需的時間和心力成本幾乎降至零,開發者自然會更頻繁地這樣做。

uv run 命令使得在正確的環境中執行程式碼,比在錯誤的環境中執行來得更簡單、更快速。這預設地培養了更穩健、更具可重複性的開發習慣,不是透過強制紀律,而是透過卓越的便利性。它將「最小阻力路徑」與開發最佳實踐重新對齊。

此外,uv 作為一個模組化、符合 PEP 標準、高效能後端的戰略設計,使其有潛力成為 Python 生態系統的「標準平面」(Standard Plane),讓其他更高層次的工具可以在其之上建構。uv 不僅僅是一個單體應用程式,更是一套針對解析、安裝和管理環境與套件的超最佳化基礎元件 7。這種架構選擇已經開始顯現成效:另一個專案管理器 PDM 已經增加了實驗性支援,可使用

uv 作為其安裝和解析的「引擎」31;而目標相似的

rip 專案則選擇停止開發,其團隊轉而貢獻並整合 uv 34。這預示著 Python 工具生態的未來可能不僅僅是單體工具之間的競爭(如 Poetry vs. PDM vs. Hatch),而可能是一個分層的架構。更高層次的工具可以在使用者體驗、外掛生態系統和特定工作流程上進行差異化競爭,同時都依賴

uv 這個「引擎」來處理效能關鍵的繁重任務。uv 正在將自己定位為 Python 打包領域的 libgit2WebKit

第 5 章:正面技術比較

表 1:功能全面比較矩陣

功能Poetryuv備註
專案管理
專案初始化 (init/new)uv 使用標準 PEP 621 格式,Poetry 使用 [tool.poetry]
依賴規格 (主要)兩者皆支援 pyproject.toml
依賴規格 (開發)是 (群組)是 (--dev)Poetry 支援多個自訂群組,uv 目前主要區分開發與非開發。
依賴規格 (自訂群組)Poetry 的群組功能更為成熟,uv 支援但相對基本。
鎖定檔案生成是 (poetry.lock)是 (uv.lock)uv.lock 是為跨平台設計的「通用」鎖定檔案。
環境管理
自動建立虛擬環境uv 預設在專案目錄下建立 .venv,Poetry 預設在快取目錄。
環境啟動 (shell)uv 鼓勵使用 uv run 而非手動啟動 shell。
在環境中執行 (run)uv run 會自動同步依賴,更為智慧。
工具鏈整合
Python 版本安裝 (pyenv-like)uv 的一大核心優勢,可取代 pyenv
獨立工具安裝 (pipx-like)uvxuv tool 可取代 pipx
單一檔案腳本執行 (PEP 723)uv 的獨特功能,適合快速腳本。
打包與發布
建構套件 (build)uv 的建構後端已趨於穩定 35
發布套件 (publish)兩者皆可發布至 PyPI 或私有源。
其他
CLI 使用者體驗直觀,動詞導向巢狀,名詞導向使用者偏好可能不同。
標準合規性 (PEP 621)否 (使用自有區段)uv 的專案更具可攜性。
效能中等極高uv 在速度上有絕對優勢。

5.1. 依賴解析與鎖定機制

  • 解析器演算法:兩者解析器的根本差異是其效能差異的主要來源。Poetry 的解析器是一個詳盡的回溯式解析器,以 Python 編寫,雖然穩健,但在處理大型複雜專案時計算成本較高 6。相比之下,uv 的解析器是專為速度而設計的,以 Rust 打造,能夠平行處理套件元數據,從而實現其驚人的速度優勢 6
  • 進階解析功能uv 為函式庫作者提供了 Poetry 所缺乏的強大功能。例如,它可以針對任意目標 Python 版本進行解析(--python-version),或使用「最低相容版本」策略(--resolution=lowest)來測試向後相容性 7uv 還引入了「覆寫」(overrides)功能,這是一個強大的應急機制,可用於修復第三方套件中錯誤的依賴元數據 7
  • 鎖定檔案:雖然兩者都使用鎖定檔案(poetry.lock, uv.lock)來確保確定性安裝,但其架構設計有所不同。uv.lock 從一開始就被設計為一個「通用」鎖定檔案。它可以在單一檔案內儲存針對多個平台(如 macOS-aarch64, linux-x86_64, windows)和不同 Python 版本的已解析依賴樹。這是一種更複雜但最終對跨平台專案更為強大的方法 3

5.2. 命令列介面(CLI)設計與可用性

為了更直觀地比較兩者的 CLI,下表將常見的開發任務對應到傳統工作流程、Poetry 和 uv 的具體命令。

表 2:CLI 羅塞塔石碑

任務傳統 pip/venvPoetryuv
建立新專案mkdir proj && cd proj && python -m venv.venvpoetry new projuv init proj
新增生產依賴pip install djangopoetry add djangouv add django
新增開發依賴pip install pytest (手動管理)poetry add pytest --group devuv add pytest --dev
安裝所有依賴pip install -r requirements.txtpoetry installuv sync
更新單一套件pip install --upgrade djangopoetry update djangouv sync --upgrade-package django
執行測試source.venv/bin/activate && pytestpoetry run pytestuv run pytest
啟動虛擬環境source.venv/bin/activatepoetry shell(不鼓勵)
  • CLI 結構分析
    • 結構:Poetry 的 CLI 結構更扁平,更偏向「動詞導向」(verb-oriented),如 poetry addpoetry build,反映了其對專案操作的關注。uv 的 CLI 則更具巢狀結構,偏向「名詞導向」(noun-oriented),其子命令對應其控制的不同領域,如 uv pipuv tooluv python 8
    • 關鍵命令的人體工學:某些命令的設計揭示了兩者哲學上的差異。例如,更新套件的命令——poetry update [pkg] vs. uv sync --upgrade-package <pkg>——顯示了 Poetry 偏好更直接、直觀的動詞,而 uv 則採用了更具描述性的、基於狀態的命令 8

5.3. 專案結構與環境管理

  • 設定檔與標準:此處再次凸顯了 PEP 合規性的差異。Poetry 在 pyproject.toml 中使用 [tool.poetry] 命名空間,這使得專案在很大程度上成為「一個 Poetry 專案」,帶來了一定程度的工具鎖定 5。相比之下,uv 使用標準的 [project] 區段,意味著專案定義更具可攜性,與特定工具解耦 5
  • 虛擬環境位置:一個實際的差異在於虛擬環境的預設位置。Poetry 預設將其儲存在一個集中的快取目錄中,這能保持專案資料夾的整潔,但可能讓 IDE 較難發現。uv 則預設在專案根目錄下建立一個 .venv 資料夾,這是一種更傳統且易於被發現的方法 19。Poetry 的此行為是可配置的(poetry config virtualenvs.in-project true)。

5.4. IDE 與開發生態整合

  • Poetry 整合
    • PyCharm:提供成熟、內建的第一方支援。它能自動偵測 pyproject.toml,允許將 Poetry 環境設定為專案直譯器,並在設定檔變更時提供 UI 操作來執行 lockupdate 36
    • VS Code:整合主要透過社群外掛(如 vscode-python-poetry)實現,這些外掛透過命令面板暴露 Poetry 的命令 38。核心整合依賴於將 Python 外掛正確指向 Poetry 建立的虛擬環境路徑 39
  • uv 整合
    • PyCharmuv 在生態系統中的快速採納令人矚目,PyCharm 已經推出了對 uv 的原生第一方支援。IDE 可以直接建立、偵測和管理 uv 環境 41。這種整合被形容為「動態二人組」,PyCharm 的程式碼分析可以建議安裝缺失的套件,而 uv 則在後台無縫地完成安裝 43
    • VS Code:目前的整合方式與其他環境管理器類似:關鍵在於設定 VS Code 的 Python 外掛,使其使用 uv 建立的 .venv 目錄中的 Python 直譯器。主要的好處是,IDE 執行的任何後台任務(如 linting 或 indexing)都將受益於 uv 的高速效能。

第 6 章:效能基準測試:速度的典範轉移

6.1. 安裝、解析與快取速度分析

  • 量化基準:廣泛引用的效能數據清晰地展示了 uv 的優勢:在冷快取(cold cache)情況下,uvpip 快 8-10 倍;在熱快取(warm cache)情況下,其速度優勢更是達到了驚人的 80-115 倍 7。在與 Poetry 的直接比較中,uv 同樣在所有方面都更快,尤其是在依賴解析階段。一個案例顯示,uv 的總耗時快了 7 倍,而解析時間更是快了幾個數量級 44
  • 快取的關鍵作用:冷快取與熱快取效能之間的區別至關重要。冷快取效能對於從零開始的 CI/CD 環境和 Docker 建構至關重要。而熱快取效能則極大地改善了開發者的日常本地開發體驗,因為開發者通常是頻繁地新增或更新單一套件 6

6.2. 架構優勢:Rust 與進階快取如何實現世代性飛躍

uv 的驚人速度並非偶然,而是源於其底層架構的根本性優勢。

  • Rust 基礎uv 基於 Rust 這一高效能的編譯語言開發,這使其相較於以 Python 編寫的 Poetry 和 pip 等工具具有根本性的優勢。Rust 避免了 Python 直譯器的開銷,並允許對記憶體和並行進行精細控制 5
  • 並行與平行uv 的架構設計使其能夠並行執行網路 I/O(如下載套件)和其他操作,而舊有工具通常是循序執行,容易產生瓶頸 6
  • 全域快取與磁碟效率uv 使用單一的全域快取來儲存套件發行版。它利用現代檔案系統的特性,如寫入時複製(Copy-on-Write, CoW)和硬連結(hardlinks)。這意味著當多個虛擬環境需要同一個套件時,其檔案在磁碟上不會被重複儲存,從而顯著節省了磁碟空間 4
  • 解析器效率uv 的解析器最佳化了網路使用。在建構依賴圖時,它最初只從 wheel 檔案中獲取輕量級的元數據,而不是下載整個套件,這極大地減少了網路傳輸和處理時間 6

第 7 章:社群健康度與未來軌跡

7.1. 社群參與、穩定性與專案成熟度

  • Poetry:Poetry 是一個成熟、穩定且廣受信任的專案,擁有一個龐大而穩固的社群。其 GitHub 指標反映了多年來的廣泛採用:擁有 33.4k 星星、2.4k 分支和 596 位貢獻者 13
  • uvuv 則是一個較新的專案,正經歷著人氣和社群參與度的爆炸性增長,常被稱為帶有「炒作」成分 46。它在 GitHub 星星數上已超越 Poetry(達到 60.8k),但貢獻者基數較小(399 位),不過正在迅速增長 4。其背後有備受尊敬的 Ruff 開發團隊 Astral 的支持,這為其提供了重要的信譽和資源 5
  • 穩定性 vs. 發展動能的權衡:這是一個風險管理的選擇。Poetry 提供了經過驗證的穩定性和可預測的演進路徑。uv 則提供了突破性的功能和效能,但其演進速度極快,本身可能成為一個移動的目標,這對於將穩定性置於首位的組織來說可能構成風險 9

7.2. 願景聲明與路線圖分析

  • Poetry 的未來:分析表明,Poetry 的未來發展可能更專注於增量改進、錯誤修復,以及在其已明確定義的範疇內,繼續打磨其作為一流專案管理器的功能 13
  • uv 的未來:「Python 的 Cargo」uv 公開聲明的願景要宏大得多。其目標是為 Python 開發建立一個完整的、端到端的整合式工具鏈 7。Astral 接管 Rye 專案 7,以及 uv 迅速實現建構後端 35 和全面的專案管理能力等功能,都清晰地證明了這一雄心。雖然目前沒有帶有時間表的公開路線圖,但其明確的發展方向是達到並超越如 Poetry、Hatch 和 PDM 等工具的功能集 10

第 8 章:戰略建議與結論

8.1. 決策框架:為您的專案與團隊選擇合適的工具

本節將整個報告的分析綜合為一個清晰、可操作的決策框架。

  • 選擇 Poetry 的時機
    • 當團隊範圍內的工作流程一致性、以及一個穩定且帶有明確主張的工具是最高優先級時。
    • 當專案是一個旨在發布的函式庫,且 Poetry 成熟、流線型的 buildpublish 命令是關鍵優勢時。
    • 當組織對於快速演進的工具所帶來的變動容忍度較低時。
    • 當前依賴管理的效能「足夠好」,且 uv 的速度優勢不足以抵銷 Poetry 穩定性帶來的價值時。
  • 選擇 uv 的時機
    • 當效能是關鍵瓶頸時,尤其是在 CI/CD 管線、Docker 建構或大型單體儲存庫(monorepo)中。
    • 當目標是透過一個單一的二進位檔案取代 pyenvpipxpip-tools,以簡化和整合開發者工具鏈時。
    • 當團隊重視靈活性和對 PEP 標準的遵守,並希望避免被鎖定在特定工具的生態系統中時。
    • 當團隊樂於接受一個快速演進的工具,並希望利用 Python 生態系統的最新進展時。

表 3:使用情境適用性計分卡

情境 / 標準Poetryuv理由
函式庫開發與發布5/54/5Poetry 的 publish 工作流程極為成熟。uv 雖已支援,但 Poetry 在此領域仍有心智佔有率優勢。
Web 應用程式開發4/55/5uv 的快速安裝和 run 命令極大提升了日常開發迭代速度。
資料科學與機器學習3/55/5這些專案通常依賴龐大,uv 的效能優勢在此極為顯著。
CI/CD 管線3/55/5uv 的冷快取效能可大幅縮短建構時間,節省成本。
單體儲存庫管理3/55/5uv 的工作區(workspace)支援和效能使其更適合大型複雜專案。
初學者專案5/54/5Poetry 的引導式工作流程對初學者更友好。uv 雖然強大,但選項較多。
原始效能2/55/5uv 在速度上無可爭議。
功能豐富度5/54/5Poetry 在某些細分功能(如自訂群組)上仍更成熟。uv 正在快速追趕。
CLI 人體工學5/54/5Poetry 的 CLI 更扁平直觀。uv 的巢狀結構功能強大但學習曲線稍高。
可重複性與確定性5/55/5兩者都透過鎖定檔案提供了極佳的確定性。
生態成熟度與穩定性5/53/5Poetry 是經過多年驗證的穩定選擇。uv 雖穩定,但仍在快速演進中。

8.2. 遷移路徑

  • pip/venv 遷移:對於傳統工作流程的使用者,兩者都是巨大的進步。poetry init 可以導入 requirements.txt 22uv 則提供了更低摩擦的路徑,它允許透過其 pip 相容介面直接使用 requirements.txt,在不改變任何工作流程的情況下立即獲得效能提升。
  • 從 Poetry 遷移至 uv:遷移過程相對直接。由於 uv 可以讀取 pyproject.toml 的標準 [project] 區段,主要工作是將 [tool.poetry] 中的特定配置翻譯過來,並更新本地腳本和 CI/CD 管線中的 CLI 命令 44

8.3. 最終結論:Python 打包的現狀與未來

Python 打包生態系統正處於一個充滿活力、健康且快速創新的時期。Poetry 為開發者體驗和工作流程整合設立了新的高標準。而現在,uv 正在為效能和工具鏈整合設立一個更高的標竿。

Poetry 仍然是一個卓越、穩健且強烈推薦的選擇,它代表了穩定、成熟和經過驗證的道路。

然而,uv 的革命性效能、宏大的願景和迅猛的發展勢頭是不可否認的。它清晰地代表了 Python 生態系統中高效能工具的未來方向。對於今天開始的新專案,特別是那些對效能有要求的專案,uv 提供了一個極具說服力,甚至可以說是決定性的選擇。問題已不再是 uv 是否會成為主導力量,而是生態系統的其他部分將以多快的速度來適應它正在設定的新標準。

分類: Uncategorized | 發佈留言

地震警報

此為預警系統自動上傳之資訊,準確信息請以交通部中央氣象署為主!

地震速報

地點:宜蘭縣近海

發生時間:2026-05-01
20:40:04

地震規模:🔵 芮氏 5.7

地震深度:🔵 40.0公里

最大震度:🟡 4級

震央位置:宜蘭縣近海

緯度:24.91

經度:121.96

發布時間:2026年05月01日 20:40:24


地震速報

地點:十勝地方南部

發生時間:2026/04/27
05:23:56

地震規模:🔴 芮氏 6.5

地震深度:🟢 90公里

最大震度:🔴 5弱級

震央位置:十勝地方南部

緯度:42.6

經度:143.1

發布時間:2026年04月27日 04:24:53


地震速報

地點:十勝地方南部

發生時間:2026/04/27
05:23:56

地震規模:🔴 芮氏 6.5

地震深度:🟢 90公里

最大震度:🔴 5弱級

震央位置:十勝地方南部

緯度:42.6

經度:143.1

發布時間:2026年04月27日 04:24:49


地震速報

地點:花蓮縣秀林鄉

發生時間:2026-04-23
01:26:15

地震規模:🟢 芮氏 4.6

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:花蓮縣秀林鄉

緯度:24.05

經度:121.55

發布時間:2026年04月23日 01:26:45


地震速報

地點:花蓮縣花蓮市

發生時間:2026-04-23
01:26:14

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:花蓮縣花蓮市

緯度:24.01

經度:121.6

發布時間:2026年04月23日 01:26:34


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:57:00


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:54


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:49


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:43


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:38


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:32


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:26


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:21


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:15


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:09


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:56:03


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.5

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:55:58


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.4

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:55:52


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.3

地震深度:🔴 30公里

最大震度:🔴 5弱級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:55:47


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.3

地震深度:🔴 30公里

最大震度:🔴 5弱級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:54:41


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.2

地震深度:🔴 30公里

最大震度:🔴 5弱級

震央位置:三陸沖

緯度:39.9

經度:143.2

發布時間:2026年04月20日 15:54:35


地震速報

地點:三陸沖

發生時間:2026/04/20
16:52:57

地震規模:🔴 芮氏 7.1

地震深度:🔴 20公里

最大震度:🔴 5弱級

震央位置:三陸沖

緯度:39.8

經度:143.2

發布時間:2026年04月20日 15:54:30


地震速報

地點:長野県北部

發生時間:2026/04/18
14:54:30

地震規模:🔵 芮氏 5.3

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.6

經度:137.9

發布時間:2026年04月18日 13:55:08


地震速報

地點:長野県北部

發生時間:2026/04/18
13:20:05

地震規模:🔵 芮氏 5.3

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.6

經度:137.9

發布時間:2026年04月18日 12:20:40


地震速報

地點:宜蘭縣南澳鄉

發生時間:2026-04-13
19:23:28

地震規模:🟢 芮氏 4.7

地震深度:🔵 50.0公里

最大震度:🟢 2級

震央位置:宜蘭縣南澳鄉

緯度:24.44

經度:121.62

發布時間:2026年04月13日 19:24:00


地震速報

地點:宜蘭縣大同鄉

發生時間:2026-04-13
19:23:29

地震規模:🟢 芮氏 4.6

地震深度:🔵 50.0公里

最大震度:🟢 2級

震央位置:宜蘭縣大同鄉

緯度:24.54

經度:121.6

發布時間:2026年04月13日 19:23:58


地震速報

地點:宜蘭縣大同鄉

發生時間:2026-04-13
19:23:29

地震規模:🟢 芮氏 4.5

地震深度:🔵 40.0公里

最大震度:🟢 2級

震央位置:宜蘭縣大同鄉

緯度:24.55

經度:121.56

發布時間:2026年04月13日 19:23:44


地震速報

地點:臺東縣中部外海

發生時間:2026-04-06
01:28:17

地震規模:🟢 芮氏 4.8

地震深度:🔴 30.0公里

最大震度:🔵 3級

震央位置:臺東縣中部外海

緯度:22.97

經度:121.51

發布時間:2026年04月05日 17:28:50


地震速報

地點:臺東縣近海

發生時間:2026-04-06
01:28:19

地震規模:🟢 芮氏 4.6

地震深度:🔴 30.0公里

最大震度:🟢 2級

震央位置:臺東縣近海

緯度:23.06

經度:121.4

發布時間:2026年04月05日 17:28:45


地震速報

地點:花蓮縣近海

發生時間:2026-04-05
05:23:58

地震規模:🟢 芮氏 4.9

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:花蓮縣近海

緯度:24.03

經度:121.71

發布時間:2026年04月04日 21:24:23


地震速報

地點:花蓮縣秀林鄉

發生時間:2026-04-05
01:14:59

地震規模:🔵 芮氏 5.6

地震深度:🔴 20.0公里

最大震度:🟡 4級

震央位置:花蓮縣秀林鄉

緯度:24.08

經度:121.6

發布時間:2026年04月04日 17:15:19


地震速報

地點:花蓮縣新城鄉

發生時間:2026-04-05
01:14:59

地震規模:🔵 芮氏 5.6

地震深度:🔴 20.0公里

最大震度:🟡 4級

震央位置:花蓮縣新城鄉

緯度:24.04

經度:121.62

發布時間:2026年04月04日 17:15:14


地震速報

地點:花蓮縣秀林鄉

發生時間:2026-04-05
01:15:01

地震規模:🔵 芮氏 5.4

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:花蓮縣秀林鄉

緯度:24.08

經度:121.58

發布時間:2026年04月04日 17:15:09


地震速報

地點:茨城県南部

發生時間:2026/04/01
10:06:17

地震規模:🔵 芮氏 5.1

地震深度:🔵 60公里

最大震度:🔴 5弱級

震央位置:茨城県南部

緯度:36.1

經度:140.0

發布時間:2026年04月01日 01:07:14


地震速報

地點:茨城県南部

發生時間:2026/04/01
10:06:17

地震規模:🔵 芮氏 5.1

地震深度:🔵 60公里

最大震度:🔴 5弱級

震央位置:茨城県南部

緯度:36.1

經度:140.0

發布時間:2026年04月01日 01:07:10


地震速報

地點:茨城県南部

發生時間:2026/04/01
10:06:17

地震規模:🔵 芮氏 5.1

地震深度:🔵 60公里

最大震度:🔴 5弱級

震央位置:茨城県南部

緯度:36.1

經度:140.0

發布時間:2026年04月01日 01:06:56


地震速報

地點:茨城県南部

發生時間:2026/04/01
10:06:18

地震規模:🔵 芮氏 5.1

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:茨城県南部

緯度:36.1

經度:140.0

發布時間:2026年04月01日 01:06:40


地震速報

地點:花蓮縣中部外海

發生時間:2026-03-31
23:43:41

地震規模:🟢 芮氏 4.7

地震深度:🔴 20.0公里

最大震度:🟢 2級

震央位置:花蓮縣中部外海

緯度:23.92

經度:121.96

發布時間:2026年03月31日 15:44:09


地震速報

地點:花蓮縣中部外海

發生時間:2026-03-31
23:43:42

地震規模:🟢 芮氏 4.6

地震深度:🔴 20.0公里

最大震度:🟢 2級

震央位置:花蓮縣中部外海

緯度:23.99

經度:121.88

發布時間:2026年03月31日 15:44:01


地震速報

地點:屏東縣來義鄉

發生時間:2026-03-29
11:12:23

地震規模:🟢 芮氏 4.6

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:屏東縣來義鄉

緯度:22.48

經度:120.65

發布時間:2026年03月29日 03:12:40


地震速報

地點:屏東縣來義鄉

發生時間:2026-03-29
11:12:22

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:屏東縣來義鄉

緯度:22.47

經度:120.64

發布時間:2026年03月29日 03:12:35


地震速報

地點:臺東縣北部外海

發生時間:2026-03-26
12:23:11

地震規模:🟢 芮氏 4.9

地震深度:🔴 30.0公里

最大震度:🔵 3級

震央位置:臺東縣北部外海

緯度:23.18

經度:121.58

發布時間:2026年03月26日 04:23:39


地震速報

地點:臺東縣北部外海

發生時間:2026-03-26
12:23:12

地震規模:🟢 芮氏 4.7

地震深度:🔵 40.0公里

最大震度:🟢 2級

震央位置:臺東縣北部外海

緯度:23.24

經度:121.49

發布時間:2026年03月26日 04:23:26


地震速報

地點:花蓮縣北部外海

發生時間:2026-03-25
01:51:01

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🟢 2級

震央位置:花蓮縣北部外海

緯度:24.26

經度:122.1

發布時間:2026年03月24日 17:51:31


地震速報

地點:花蓮縣壽豐鄉

發生時間:2026-03-20
21:34:14

地震規模:🟢 芮氏 4.6

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:花蓮縣壽豐鄉

緯度:23.87

經度:121.51

發布時間:2026年03月20日 13:34:36


地震速報

地點:花蓮縣壽豐鄉

發生時間:2026-03-20
21:34:13

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:花蓮縣壽豐鄉

緯度:23.85

經度:121.56

發布時間:2026年03月20日 13:34:33


地震速報

地點:花蓮縣近海

發生時間:2026-03-20
21:32:43

地震規模:🔵 芮氏 5.2

地震深度:🔵 40.0公里

最大震度:🔵 3級

震央位置:花蓮縣近海

緯度:23.84

經度:121.6

發布時間:2026年03月20日 13:32:55


地震速報

地點:花蓮縣萬榮鄉

發生時間:2026-03-20
10:18:33

地震規模:🟢 芮氏 4.7

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:花蓮縣萬榮鄉

緯度:23.55

經度:121.34

發布時間:2026年03月20日 02:18:48


地震速報

地點:臺南市楠西區

發生時間:2026-03-16
07:19:52

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.22

經度:120.49

發布時間:2026年03月15日 23:20:06


地震速報

地點:宜蘭縣南部外海

發生時間:2026-03-15
16:14:56

地震規模:🔵 芮氏 5.5

地震深度:🔴 30.0公里

最大震度:🔵 3級

震央位置:宜蘭縣南部外海

緯度:24.34

經度:121.98

發布時間:2026年03月15日 08:15:14


地震速報

地點:宜蘭縣近海

發生時間:2026-03-15
16:15:01

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.46

經度:121.9

發布時間:2026年03月15日 08:15:09


地震速報

地點:宜蘭縣近海

發生時間:2026-03-15
02:58:50

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.36

經度:121.82

發布時間:2026年03月14日 18:59:11


地震速報

地點:花蓮縣壽豐鄉

發生時間:2026-03-12
20:14:14

地震規模:🔵 芮氏 5.8

地震深度:🔴 20.0公里

最大震度:🟡 4級

震央位置:花蓮縣壽豐鄉

緯度:23.78

經度:121.53

發布時間:2026年03月12日 12:14:37


地震速報

地點:花蓮縣壽豐鄉

發生時間:2026-03-12
20:14:14

地震規模:🔵 芮氏 5.7

地震深度:🔴 20.0公里

最大震度:🟡 4級

震央位置:花蓮縣壽豐鄉

緯度:23.78

經度:121.53

發布時間:2026年03月12日 12:14:35


地震速報

地點:花蓮縣壽豐鄉

發生時間:2026-03-12
20:14:14

地震規模:🔵 芮氏 5.6

地震深度:🔴 20.0公里

最大震度:🟡 4級

震央位置:花蓮縣壽豐鄉

緯度:23.76

經度:121.52

發布時間:2026年03月12日 12:14:31


地震速報

地點:花蓮縣鳳林鎮

發生時間:2026-03-12
20:14:16

地震規模:🔵 芮氏 5.4

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:花蓮縣鳳林鎮

緯度:23.78

經度:121.5

發布時間:2026年03月12日 12:14:24


地震速報

地點:臺中市大里區

發生時間:2026-03-06
23:14:26

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:臺中市大里區

緯度:24.1

經度:120.67

發布時間:2026年03月06日 15:14:50


地震速報

地點:臺南市楠西區

發生時間:2026-03-03
23:34:30

地震規模:🟢 芮氏 4.7

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.22

經度:120.5

發布時間:2026年03月03日 15:34:57


地震速報

地點:臺南市楠西區

發生時間:2026-03-03
23:34:30

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.21

經度:120.48

發布時間:2026年03月03日 15:34:41


地震速報

地點:臺南市官田區

發生時間:2026-03-03
19:52:49

地震規模:🔵 芮氏 5.2

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:臺南市官田區

緯度:23.19

經度:120.41

發布時間:2026年03月03日 11:52:57


地震速報

地點:宜蘭縣近海

發生時間:2026-02-28
23:49:51

地震規模:🟢 芮氏 4.6

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:宜蘭縣近海

緯度:24.38

經度:121.8

發布時間:2026年02月28日 15:50:08


地震速報

地點:宜蘭縣近海

發生時間:2026-02-28
23:49:51

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:宜蘭縣近海

緯度:24.39

經度:121.83

發布時間:2026年02月28日 15:50:04


地震速報

地點:臺東縣近海

發生時間:2026-02-26
06:53:22

地震規模:🟢 芮氏 4.5

地震深度:🔴 20.0公里

最大震度:🔵 3級

震央位置:臺東縣近海

緯度:22.78

經度:121.24

發布時間:2026年02月25日 22:53:51


地震速報

地點:臺南市南化區

發生時間:2026-02-25
01:23:11

地震規模:🟢 芮氏 4.7

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:臺南市南化區

緯度:23.11

經度:120.53

發布時間:2026年02月24日 17:23:20


地震速報

地點:宜蘭縣近海

發生時間:2026-02-24
12:37:19

地震規模:🔵 芮氏 5.5

地震深度:🔴 30.0公里

最大震度:🟡 4級

震央位置:宜蘭縣近海

緯度:24.66

經度:121.87

發布時間:2026年02月24日 04:37:33


地震速報

地點:宜蘭縣冬山鄉

發生時間:2026-02-24
12:37:23

地震規模:🟢 芮氏 4.8

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:宜蘭縣冬山鄉

緯度:24.66

經度:121.81

發布時間:2026年02月24日 04:37:31


地震速報

地點:臺東縣金峰鄉

發生時間:2026-02-23
01:01:04

地震規模:🟢 芮氏 4.6

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:臺東縣金峰鄉

緯度:22.66

經度:120.8

發布時間:2026年02月22日 17:01:16


地震速報

地點:宜蘭縣北部外海

發生時間:2026-02-17
02:23:19

地震規模:🟢 芮氏 4.5

地震深度:🔴 30.0公里

最大震度:🟢 2級

震央位置:宜蘭縣北部外海

緯度:24.66

經度:121.97

發布時間:2026年02月16日 18:23:34


地震速報

地點:恆春半島近海

發生時間:2026-01-27
02:48:40

地震規模:🔵 芮氏 5.0

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:恆春半島近海

緯度:21.87

經度:120.87

發布時間:2026年01月26日 18:49:04


地震速報

地點:恆春半島近海

發生時間:2026-01-27
02:48:40

地震規模:🟢 芮氏 4.8

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:恆春半島近海

緯度:21.86

經度:120.85

發布時間:2026年01月26日 18:48:59


地震速報

地點:宜蘭縣近海

發生時間:2026-01-24
22:26:24

地震規模:🟢 芮氏 4.6

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.35

經度:121.81

發布時間:2026年01月24日 14:26:50


地震速報

地點:宜蘭縣近海

發生時間:2026-01-24
22:26:24

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.34

經度:121.82

發布時間:2026年01月24日 14:26:47


地震速報

地點:宜蘭縣近海

發生時間:2026-01-24
22:26:24

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.35

經度:121.81

發布時間:2026年01月24日 14:26:43


地震速報

地點:宜蘭縣南部外海

發生時間:2026-01-23
13:41:08

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣南部外海

緯度:24.3

經度:121.9

發布時間:2026年01月23日 05:41:45


地震速報

地點:宜蘭縣近海

發生時間:2026-01-18
01:01:30

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.33

經度:121.81

發布時間:2026年01月17日 17:01:47


地震速報

地點:宜蘭縣近海

發生時間:2026-01-18
01:01:30

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🔵 3級

震央位置:宜蘭縣近海

緯度:24.32

經度:121.8

發布時間:2026年01月17日 17:01:43


地震速報

地點:宜蘭縣南部外海

發生時間:2026-01-16
11:09:33

地震規模:🟢 芮氏 4.8

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:宜蘭縣南部外海

緯度:24.44

經度:121.93

發布時間:2026年01月16日 03:09:53


地震速報

地點:宜蘭縣南澳鄉

發生時間:2026-01-16
11:09:35

地震規模:🟢 芮氏 4.5

地震深度:🔴 10.0公里

最大震度:🟡 4級

震央位置:宜蘭縣南澳鄉

緯度:24.54

經度:121.81

發布時間:2026年01月16日 03:09:48


地震速報

地點:宜蘭縣近海

發生時間:2026-01-12
21:31:55

地震規模:🟢 芮氏 4.6

地震深度:🔴 30.0公里

最大震度:🟢 2級

震央位置:宜蘭縣近海

緯度:24.73

經度:121.89

發布時間:2026年01月12日 13:32:16


地震速報

地點:岩手県沿岸北部

發生時間:2026/01/11
13:15:34

地震規模:🔵 芮氏 5.2

地震深度:🟢 80公里

最大震度:🔴 5弱級

震央位置:岩手県沿岸北部

緯度:39.5

經度:141.9

發布時間:2026年01月11日 04:16:32


地震速報

地點:岩手県沿岸北部

發生時間:2026/01/11
13:15:34

地震規模:🔵 芮氏 5.2

地震深度:🔵 70公里

最大震度:🔴 5弱級

震央位置:岩手県沿岸北部

緯度:39.5

經度:141.9

發布時間:2026年01月11日 04:16:15


地震速報

地點:岩手県沿岸北部

發生時間:2026/01/11
13:15:34

地震規模:🔵 芮氏 5.2

地震深度:🔵 70公里

最大震度:🔴 5弱級

震央位置:岩手県沿岸北部

緯度:39.5

經度:141.9

發布時間:2026年01月11日 04:16:05


地震速報

地點:岩手県沿岸北部

發生時間:2026/01/11
13:15:35

地震規模:🔵 芮氏 5.2

地震深度:🔵 60公里

最大震度:🔴 5弱級

震央位置:岩手県沿岸北部

緯度:39.5

經度:141.9

發布時間:2026年01月11日 04:16:01


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:46

地震規模:🔵 芮氏 5.6

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:38:11


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:46

地震規模:🔵 芮氏 5.6

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:38:09


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:46

地震規模:🔵 芮氏 5.3

地震深度:🔴 20公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:38:07


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:37

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:38:05


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:37

地震規模:🟢 芮氏 4.8

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:38:03


地震速報

地點:島根県東部

發生時間:2026/01/06
10:37:37

地震規模:🟢 芮氏 4.8

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:37:59


地震速報

地點:島根県東部

發生時間:2026/01/06
10:28:48

地震規模:🔵 芮氏 5.1

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:29:41


地震速報

地點:島根県東部

發生時間:2026/01/06
10:28:48

地震規模:🔵 芮氏 5.1

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:29:37


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:20:27


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:20:25


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:20:05


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:55


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:53


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:51


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:49


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 20公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:47


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.3

地震深度:🔴 20公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:45


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.2

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:43


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.2

地震深度:🔴 20公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:42


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.2

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:36


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.2

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:34


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔴 芮氏 6.2

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:32


地震速報

地點:島根県東部

發生時間:2026/01/06
10:18:46

地震規模:🔵 芮氏 5.8

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:島根県東部

緯度:35.3

經度:133.2

發布時間:2026年01月06日 01:19:28


地震速報

地點:宜蘭縣羅東鎮

發生時間:2026-01-04
03:52:50

地震規模:🟢 芮氏 4.6

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:宜蘭縣羅東鎮

緯度:24.7

經度:121.76

發布時間:2026年01月03日 19:53:08


地震速報

地點:宜蘭縣蘇澳鎮

發生時間:2026-01-03
20:58:02

地震規模:🟢 芮氏 4.8

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:宜蘭縣蘇澳鎮

緯度:24.6

經度:121.82

發布時間:2026年01月03日 12:58:22


地震速報

地點:綠島附近

發生時間:2025-12-28
07:03:25

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:綠島附近

緯度:22.65

經度:121.24

發布時間:2025年12月27日 23:04:03


地震速報

地點:臺東縣近海

發生時間:2025-12-28
07:03:25

地震規模:🟢 芮氏 4.5

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:臺東縣近海

緯度:22.71

經度:121.16

發布時間:2025年12月27日 23:03:51


地震速報

地點:宜蘭縣北部外海

發生時間:2025-12-28
00:45:45

地震規模:🟢 芮氏 4.7

地震深度:🔵 50公里

最大震度:🟢 2級

震央位置:宜蘭縣北部外海

緯度:24.63

經度:122.15

發布時間:2025年12月27日 16:46:17


地震速報

地點:宜蘭縣近海

發生時間:2025-12-28
00:45:47

地震規模:🟢 芮氏 4.5

地震深度:🔵 50公里

最大震度:🟢 2級

震央位置:宜蘭縣近海

緯度:24.66

經度:121.87

發布時間:2025年12月27日 16:46:12


地震速報

地點:宜蘭縣近海

發生時間:2025-12-27
23:06:01

地震規模:🔴 芮氏 7.4

地震深度:🔵 40公里

最大震度:🔴 6強級

震央位置:宜蘭縣近海

緯度:24.69

經度:121.89

發布時間:2025年12月27日 15:06:18


地震速報

地點:臺東縣延平鄉

發生時間:2025-12-25
03:41:12

地震規模:🟢 芮氏 4.7

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺東縣延平鄉

緯度:22.91

經度:121.03

發布時間:2025年12月24日 19:41:30


地震速報

地點:臺東縣延平鄉

發生時間:2025-12-24
17:47:06

地震規模:🔴 芮氏 6.5

地震深度:🔴 10公里

最大震度:🔴 6弱級

震央位置:臺東縣延平鄉

緯度:22.91

經度:121.03

發布時間:2025年12月24日 09:47:22


地震速報

地點:花蓮縣近海

發生時間:2025-12-18
19:32:52

地震規模:🔵 芮氏 5.3

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:花蓮縣近海

緯度:24.09

經度:121.69

發布時間:2025年12月18日 11:33:10


地震速報

地點:花蓮縣北部外海

發生時間:2025-12-14
01:58:36

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:花蓮縣北部外海

緯度:24.24

經度:121.84

發布時間:2025年12月13日 17:59:06


地震速報

地點:青森県東方沖

發生時間:2025/12/12
11:44:13

地震規模:🔴 芮氏 6.8

地震深度:🔴 30公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:40.9

經度:143.0

發布時間:2025年12月12日 02:44:36


地震速報

地點:青森県東方沖

發生時間:2025/12/12
11:44:13

地震規模:🔴 芮氏 6.8

地震深度:🔴 30公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:40.9

經度:143.0

發布時間:2025年12月12日 02:44:33


地震速報

地點:臺南市楠西區

發生時間:2025-12-12
04:24:29

地震規模:🟢 芮氏 4.6

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.2

經度:120.48

發布時間:2025年12月11日 20:24:51


地震速報

地點:高雄市甲仙區

發生時間:2025-12-11
23:19:41

地震規模:🔵 芮氏 5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市甲仙區

緯度:23.19

經度:120.68

發布時間:2025年12月11日 15:20:06


地震速報

地點:高雄市甲仙區

發生時間:2025-12-11
23:19:41

地震規模:🟢 芮氏 4.8

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市甲仙區

緯度:23.19

經度:120.67

發布時間:2025年12月11日 15:19:58


地震速報

地點:高雄市甲仙區

發生時間:2025-12-11
22:49:03

地震規模:🟢 芮氏 4.7

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市甲仙區

緯度:23.18

經度:120.67

發布時間:2025年12月11日 14:49:23


地震速報

地點:臺東縣北部外海

發生時間:2025-12-09
20:01:47

地震規模:🟢 芮氏 4.9

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:臺東縣北部外海

緯度:23.16

經度:121.66

發布時間:2025年12月09日 12:02:14


地震速報

地點:臺東縣成功鎮

發生時間:2025-12-09
20:01:48

地震規模:🟢 芮氏 4.5

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:臺東縣成功鎮

緯度:23.2

經度:121.39

發布時間:2025年12月09日 12:02:07


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:19:40


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:19:33


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:19:09


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:19:03


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:57


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:51


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:45


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:38


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:32


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:25


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:19


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:18:13


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:54


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:48


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 50公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:36


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:30


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 50公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:23


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.2

地震深度:🔵 60公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:16


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 7.2

地震深度:🔵 50公里

最大震度:🔴 6弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:12


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.1

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:17:06


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.1

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:53


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 7.1

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:47


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 7.0

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:42


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:10

地震規模:🔴 芮氏 7.0

地震深度:🔵 60公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:36


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.9

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:30


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.8

地震深度:🔵 50公里

最大震度:🔴 5強級

震央位置:青森県東方沖

緯度:41.0

經度:142.2

發布時間:2025年12月08日 14:16:25


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.8

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.3

發布時間:2025年12月08日 14:16:19


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.7

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:41.0

經度:142.3

發布時間:2025年12月08日 14:16:14


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.7

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:40.9

經度:142.3

發布時間:2025年12月08日 14:16:08


地震速報

地點:青森県東方沖

發生時間:2025/12/08
23:15:11

地震規模:🔴 芮氏 6.4

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:青森県東方沖

緯度:40.9

經度:142.3

發布時間:2025年12月08日 14:16:03


地震速報

地點:花蓮縣壽豐鄉

發生時間:2025-12-08
19:24:57

地震規模:🔵 芮氏 5.6

地震深度:🔴 20公里

最大震度:🟡 4級

震央位置:花蓮縣壽豐鄉

緯度:23.88

經度:121.56

發布時間:2025年12月08日 11:25:28


地震速報

地點:花蓮縣瑞穗鄉

發生時間:2025-12-07
06:48:02

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣瑞穗鄉

緯度:23.46

經度:121.46

發布時間:2025年12月06日 22:48:34


地震速報

地點:花蓮縣瑞穗鄉

發生時間:2025-12-07
06:48:02

地震規模:🟢 芮氏 4.6

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:花蓮縣瑞穗鄉

緯度:23.48

經度:121.36

發布時間:2025年12月06日 22:48:25


地震速報

地點:宜蘭縣近海

發生時間:2025-12-02
10:01:23

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:宜蘭縣近海

緯度:24.41

經度:121.86

發布時間:2025年12月02日 02:01:53


地震速報

地點:花蓮縣近海

發生時間:2025-11-26
23:12:55

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣近海

緯度:24.24

經度:121.77

發布時間:2025年11月26日 15:13:25


地震速報

地點:花蓮縣近海

發生時間:2025-11-26
23:12:56

地震規模:🟢 芮氏 4.5

地震深度:🔴 20公里

最大震度:🟢 2級

震央位置:花蓮縣近海

緯度:24.25

經度:121.77

發布時間:2025年11月26日 15:13:21


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:02:11


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:02:10


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:50


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:41


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:38


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:36


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:34


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:33


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:31


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.5

地震深度:🔴 10公里

最大震度:🔴 5強級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:29


地震速報

地點:熊本県阿蘇地方

發生時間:2025/11/25
18:01:16

地震規模:🔵 芮氏 5.5

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:熊本県阿蘇地方

緯度:33.0

經度:131.1

發布時間:2025年11月25日 09:01:26


地震速報

地點:雲林縣古坑鄉

發生時間:2025-11-21
03:43:57

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:雲林縣古坑鄉

緯度:23.58

經度:120.66

發布時間:2025年11月20日 19:44:20


地震速報

地點:花蓮縣近海

發生時間:2025-11-19
20:38:58

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:花蓮縣近海

緯度:24.15

經度:121.74

發布時間:2025年11月19日 12:39:24


地震速報

地點:花蓮縣北部外海

發生時間:2025-11-19
20:25:14

地震規模:🟢 芮氏 4.9

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:花蓮縣北部外海

緯度:24.12

經度:121.8

發布時間:2025年11月19日 12:25:45


地震速報

地點:花蓮縣北部外海

發生時間:2025-11-19
20:25:14

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:花蓮縣北部外海

緯度:24.12

經度:121.82

發布時間:2025年11月19日 12:25:41


地震速報

地點:宜蘭縣北部外海

發生時間:2025-11-15
07:56:26

地震規模:🟢 芮氏 4.6

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:宜蘭縣北部外海

緯度:24.9

經度:122.02

發布時間:2025年11月14日 23:56:59


地震速報

地點:新北市烏來區

發生時間:2025-11-13
09:22:42

地震規模:🟢 芮氏 4.5

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:新北市烏來區

緯度:24.8

經度:121.59

發布時間:2025年11月13日 01:23:09


地震速報

地點:南投縣國姓鄉

發生時間:2025-11-12
04:26:39

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:南投縣國姓鄉

緯度:24.04

經度:120.9

發布時間:2025年11月11日 20:27:03


地震速報

地點:高雄市甲仙區

發生時間:2025-11-10
13:00:49

地震規模:🔵 芮氏 5.4

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市甲仙區

緯度:23.19

經度:120.68

發布時間:2025年11月10日 05:01:07


地震速報

地點:高雄市甲仙區

發生時間:2025-11-10
13:00:49

地震規模:🔵 芮氏 5.3

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市甲仙區

緯度:23.19

經度:120.68

發布時間:2025年11月10日 05:01:02


地震速報

地點:根室半島南東沖

發生時間:2025/10/25
01:40:09

地震規模:🔴 芮氏 6.2

地震深度:🔵 40公里

最大震度:🔴 5弱級

震央位置:根室半島南東沖

緯度:43.0

經度:145.7

發布時間:2025年10月24日 16:40:32


地震速報

地點:根室半島南東沖

發生時間:2025/10/25
01:40:09

地震規模:🔴 芮氏 6.2

地震深度:🔵 40公里

最大震度:🔴 5弱級

震央位置:根室半島南東沖

緯度:43.0

經度:145.7

發布時間:2025年10月24日 16:40:30


地震速報

地點:根室半島南東沖

發生時間:2025/10/25
01:40:09

地震規模:🔴 芮氏 6.2

地震深度:🔵 40公里

最大震度:🔴 5弱級

震央位置:根室半島南東沖

緯度:43.0

經度:145.7

發布時間:2025年10月24日 16:40:29


地震速報

地點:根室半島南東沖

發生時間:2025/10/25
01:40:09

地震規模:🔴 芮氏 6.2

地震深度:🔵 50公里

最大震度:🔴 5弱級

震央位置:根室半島南東沖

緯度:42.9

經度:145.7

發布時間:2025年10月24日 16:40:27


地震速報

地點:根室半島南東沖

發生時間:2025/10/25
01:40:11

地震規模:🔴 芮氏 6.2

地震深度:🔴 30公里

最大震度:🔴 5強級

震央位置:根室半島南東沖

緯度:43.0

經度:145.6

發布時間:2025年10月24日 16:40:23


地震速報

地點:南投縣中寮鄉

發生時間:2025-10-23
20:28:07

地震規模:🟢 芮氏 4.7

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:南投縣中寮鄉

緯度:23.87

經度:120.77

發布時間:2025年10月23日 12:28:26


地震速報

地點:臺東縣北部外海

發生時間:2025-10-18
15:31:42

地震規模:🟢 芮氏 4.9

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:臺東縣北部外海

緯度:23.43

經度:121.64

發布時間:2025年10月18日 07:32:16


地震速報

地點:花蓮縣玉里鎮

發生時間:2025-10-18
15:31:46

地震規模:🟢 芮氏 4.5

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣玉里鎮

緯度:23.35

經度:121.38

發布時間:2025年10月18日 07:32:11


地震速報

地點:宜蘭縣南部外海

發生時間:2025-10-18
10:04:15

地震規模:🔵 芮氏 5.4

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:宜蘭縣南部外海

緯度:24.31

經度:122.07

發布時間:2025年10月18日 02:04:37


地震速報

地點:宜蘭縣南部外海

發生時間:2025-10-18
10:04:16

地震規模:🔵 芮氏 5

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:宜蘭縣南部外海

緯度:24.41

經度:122.04

發布時間:2025年10月18日 02:04:33


地震速報

地點:花蓮縣南部外海

發生時間:2025-10-08
11:33:55

地震規模:🔵 芮氏 5.1

地震深度:🔴 30公里

最大震度:🟢 2級

震央位置:花蓮縣南部外海

緯度:23.55

經度:122

發布時間:2025年10月08日 03:34:35


地震速報

地點:花蓮縣吉安鄉

發生時間:2025-10-08
07:52:12

地震規模:🔵 芮氏 5.4

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:花蓮縣吉安鄉

緯度:23.96

經度:121.57

發布時間:2025年10月07日 23:52:39


地震速報

地點:花蓮縣吉安鄉

發生時間:2025-10-08
07:52:13

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:花蓮縣吉安鄉

緯度:23.95

經度:121.57

發布時間:2025年10月07日 23:52:33


地震速報

地點:南投縣信義鄉

發生時間:2025-09-22
03:20:15

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:南投縣信義鄉

緯度:23.72

經度:120.89

發布時間:2025年09月21日 19:20:34


地震速報

地點:花蓮縣花蓮市

發生時間:2025-09-19
05:21:41

地震規模:🟢 芮氏 4.7

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣花蓮市

緯度:24.01

經度:121.63

發布時間:2025年09月18日 21:22:08


地震速報

地點:花蓮縣吉安鄉

發生時間:2025-09-19
05:21:42

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣吉安鄉

緯度:23.99

經度:121.59

發布時間:2025年09月18日 21:22:01


地震速報

地點:臺南市楠西區

發生時間:2025-09-12
03:28:11

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.22

經度:120.55

發布時間:2025年09月12日 16:31:09


地震速報

地點:臺南市楠西區

發生時間:2025-09-12
03:28:11

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.22

經度:120.55

發布時間:2025年09月11日 19:28:31


地震速報

地點:花蓮縣北部外海

發生時間:2025-09-07
19:29:17

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🟢 2級

震央位置:花蓮縣北部外海

緯度:24.23

經度:122.09

發布時間:2025年09月07日 11:29:57


地震速報

地點:臺南市南化區

發生時間:2025-09-05
14:57:42

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:臺南市南化區

緯度:23.19

經度:120.58

發布時間:2025年09月05日 06:57:56


地震速報

地點:高雄市六龜區

發生時間:2025-09-02
14:09:22

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市六龜區

緯度:22.91

經度:120.64

發布時間:2025年09月02日 06:09:46


地震速報

地點:新北市瑞芳區

發生時間:2025-08-27
21:11:10

地震規模:🔵 芮氏 5.6

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:新北市瑞芳區

緯度:25.08

經度:121.84

發布時間:2025年08月27日 13:11:35


地震速報

地點:新北市瑞芳區

發生時間:2025-08-27
21:11:10

地震規模:🔵 芮氏 5.5

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:新北市瑞芳區

緯度:25.08

經度:121.83

發布時間:2025年08月27日 13:11:32


地震速報

地點:花蓮縣北部外海

發生時間:2025-08-24
20:55:07

地震規模:🔵 芮氏 5.1

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣北部外海

緯度:24.14

經度:121.79

發布時間:2025年08月24日 12:55:31


地震速報

地點:花蓮縣北部外海

發生時間:2025-08-24
20:55:06

地震規模:🔵 芮氏 5.1

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:花蓮縣北部外海

緯度:24.17

經度:121.91

發布時間:2025年08月24日 12:55:28


地震速報

地點:花蓮縣花蓮市

發生時間:2025-08-19
09:26:09

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣花蓮市

緯度:24

經度:121.64

發布時間:2025年08月19日 01:26:25


地震速報

地點:花蓮縣北部外海

發生時間:2025-08-19
03:55:47

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🟢 2級

震央位置:花蓮縣北部外海

緯度:24.1

經度:121.88

發布時間:2025年08月18日 19:56:23


地震速報

地點:花蓮縣鳳林鎮

發生時間:2025-08-10
14:03:37

地震規模:🔵 芮氏 5.1

地震深度:🔴 20公里

最大震度:🟡 4級

震央位置:花蓮縣鳳林鎮

緯度:23.76

經度:121.5

發布時間:2025年08月10日 06:03:55


地震速報

地點:與那國島附近

發生時間:2025-08-07
15:45:11

地震規模:🔴 芮氏 6.1

地震深度:🔵 70公里

最大震度:🔵 3級

震央位置:與那國島附近

緯度:24.49

經度:122.76

發布時間:2025年08月07日 07:45:43


地震速報

地點:宜蘭縣南部外海

發生時間:2025-08-07
15:45:23

地震規模:🟢 芮氏 4.8

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:宜蘭縣南部外海

緯度:24.46

經度:122.08

發布時間:2025年08月07日 07:45:39


地震速報

地點:恆春半島近海

發生時間:2025-07-15
21:58:25

地震規模:🟢 芮氏 4.6

地震深度:🔴 10公里

最大震度:🔵 3級

震央位置:恆春半島近海

緯度:21.88

經度:120.85

發布時間:2025年07月15日 13:58:44


地震速報

地點:臺東縣近海

發生時間:2025-07-09
18:46:26

地震規模:🟢 芮氏 4.5

地震深度:🔴 30公里

最大震度:🟢 2級

震央位置:臺東縣近海

緯度:23.38

經度:121.48

發布時間:2025年07月09日 10:46:46


地震速報

地點:花蓮縣秀林鄉

發生時間:2025-07-08
03:57:06

地震規模:🔵 芮氏 5.2

地震深度:🔴 20公里

最大震度:🟡 4級

震央位置:花蓮縣秀林鄉

緯度:23.95

經度:121.48

發布時間:2025年07月07日 19:57:25


地震速報

地點:宜蘭縣南澳鄉

發生時間:2025-07-07
20:01:32

地震規模:🟢 芮氏 4.8

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:宜蘭縣南澳鄉

緯度:24.55

經度:121.76

發布時間:2025年07月07日 12:01:55


地震速報

地點:宜蘭縣南澳鄉

發生時間:2025-07-07
20:01:32

地震規模:🟢 芮氏 4.8

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:宜蘭縣南澳鄉

緯度:24.53

經度:121.79

發布時間:2025年07月07日 12:01:47


地震速報

地點:花蓮縣中部外海

發生時間:2025-07-05
07:35:41

地震規模:🟢 芮氏 4.7

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣中部外海

緯度:23.89

經度:121.81

發布時間:2025年07月05日 07:36:04


地震速報

地點:花蓮縣中部外海

發生時間:2025-07-05
07:12:42

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣中部外海

緯度:23.9

經度:121.8

發布時間:2025年07月05日 07:13:06


地震速報

地點:トカラ列島近海

發生時間:2025/07/02
15:26:41

地震規模:🔴 芮氏 6.1

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:トカラ列島近海

緯度:29.2

經度:129.1

發布時間:2025年07月02日 14:26:59


地震速報

地點:臺南市東山區

發生時間:2025-06-30
16:26:23

地震規模:🟢 芮氏 4.7

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市東山區

緯度:23.23

經度:120.48

發布時間:2025年06月30日 16:26:35


地震速報

地點:臺南市楠西區

發生時間:2025-06-30
16:22:48

地震規模:🟢 芮氏 4.7

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市楠西區

緯度:23.22

經度:120.48

發布時間:2025年06月30日 16:22:50


地震速報

地點:花蓮縣鳳林鎮

發生時間:2025-06-24
02:01:00

地震規模:🟢 芮氏 4.9

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:花蓮縣鳳林鎮

緯度:23.78

經度:121.49

發布時間:2025年06月24日 02:01:13


地震速報

地點:トカラ列島近海

發生時間:2025/06/22
17:15:04

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:トカラ列島近海

緯度:29.3

經度:129.3

發布時間:2025年06月22日 16:16:00


地震速報

地點:トカラ列島近海

發生時間:2025/06/22
17:15:04

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:トカラ列島近海

緯度:29.3

經度:129.3

發布時間:2025年06月22日 16:15:58


地震速報

地點:トカラ列島近海

發生時間:2025/06/22
17:15:04

地震規模:🔵 芮氏 5.7

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:トカラ列島近海

緯度:29.3

經度:129.3

發布時間:2025年06月22日 16:15:29


地震速報

地點:花蓮縣萬榮鄉

發生時間:2025-06-15
05:07:13

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:花蓮縣萬榮鄉

緯度:23.49

經度:121.32

發布時間:2025年06月15日 05:07:36


地震速報

地點:臺東縣近海

發生時間:2025-06-12
00:01:05

地震規模:🔵 芮氏 5.1

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:臺東縣近海

緯度:23.39

經度:121.52

發布時間:2025年06月12日 00:01:01


地震速報

地點:臺東縣長濱鄉

發生時間:2025-06-11
19:00:31

地震規模:🔴 芮氏 6.9

地震深度:🔵 40公里

最大震度:🔴 5強級

震央位置:臺東縣長濱鄉

緯度:23.42

經度:121.45

發布時間:2025年06月11日 19:00:28


地震速報

地點:臺東縣近海

發生時間:2025-05-19
03:55:35

地震規模:🟢 芮氏 4.5

地震深度:🔴 30公里

最大震度:🟢 2級

震央位置:臺東縣近海

緯度:22.99

經度:121.34

發布時間:2025年05月19日 03:56:08


地震速報

地點:臺東縣東河鄉

發生時間:2025-05-14
10:48:17

地震規模:🔴 芮氏 6.4

地震深度:🟢 80公里

最大震度:🟡 4級

震央位置:臺東縣東河鄉

緯度:22.95

經度:121.23

發布時間:2025年05月14日 10:48:43


地震速報

地點:宜蘭縣北部外海

發生時間:2025-05-12
05:25:52

地震規模:🟢 芮氏 4.5

地震深度:🔴 20公里

最大震度:🟢 2級

震央位置:宜蘭縣北部外海

緯度:24.71

經度:122.26

發布時間:2025年05月12日 05:26:29


地震速報

地點:彰化縣二水鄉

發生時間:2025-05-10
05:27:50

地震規模:🟢 芮氏 4.5

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:彰化縣二水鄉

緯度:23.8

經度:120.67

發布時間:2025年05月10日 05:28:18


地震速報

地點:長野県北部

發生時間:2025/04/18
20:19:29

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.5

經度:137.9

發布時間:2025年04月18日 19:19:45


地震速報

地點:長野県北部

發生時間:2025/04/18
20:19:29

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.5

經度:137.9

發布時間:2025年04月18日 19:19:44


地震速報

地點:長野県北部

發生時間:2025/04/18
20:19:29

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.5

經度:137.9

發布時間:2025年04月18日 19:19:42


地震速報

地點:長野県北部

發生時間:2025/04/18
20:19:28

地震規模:🔵 芮氏 5.2

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.5

經度:137.9

發布時間:2025年04月18日 19:19:40


地震速報

地點:長野県北部

發生時間:2025/04/18
20:19:28

地震規模:🟢 芮氏 4.9

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:長野県北部

緯度:36.5

經度:137.9

發布時間:2025年04月18日 19:19:37


地震速報

地點:花蓮縣卓溪鄉

發生時間:2025-04-10
08:31:04

地震規模:🟢 芮氏 4.7

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣卓溪鄉

緯度:23.36

經度:121.29

發布時間:2025年04月10日 08:31:17


地震速報

地點:宜蘭縣冬山鄉

發生時間:2025-04-09
09:53:31

地震規模:🔵 芮氏 5.2

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:宜蘭縣冬山鄉

緯度:24.63

經度:121.74

發布時間:2025年04月09日 09:53:44


地震速報

地點:宜蘭縣蘇澳鎮

發生時間:2025-04-09
09:53:31

地震規模:🔵 芮氏 5

地震深度:🔴 30公里

最大震度:🔵 3級

震央位置:宜蘭縣蘇澳鎮

緯度:24.59

經度:121.82

發布時間:2025年04月09日 09:53:42


地震速報

地點:宜蘭縣南澳鄉

發生時間:2025-04-09
09:53:34

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:宜蘭縣南澳鄉

緯度:24.58

經度:121.79

發布時間:2025年04月09日 09:53:39


地震速報

地點:臺南市六甲區

發生時間:2025-04-05
20:09:04

地震規模:🟢 芮氏 4.7

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市六甲區

緯度:23.22

經度:120.4

發布時間:2025年04月05日 20:09:17


地震速報

地點:臺南市六甲區

發生時間:2025-04-05
20:09:03

地震規模:🟢 芮氏 4.6

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:臺南市六甲區

緯度:23.21

經度:120.38

發布時間:2025年04月05日 20:09:14


地震速報

地點:臺南市六甲區

發生時間:2025-04-03
11:47:01

地震規模:🔵 芮氏 5.5

地震深度:🔴 10公里

最大震度:🔴 5弱級

震央位置:臺南市六甲區

緯度:23.21

經度:120.38

發布時間:2025年04月03日 11:47:08


地震速報

地點:花蓮縣秀林鄉

發生時間:2025-04-03
02:01:35

地震規模:🟢 芮氏 4.9

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:花蓮縣秀林鄉

緯度:24.07

經度:121.56

發布時間:2025年04月03日 02:01:51


地震速報

地點:花蓮縣秀林鄉

發生時間:2025-04-03
02:01:35

地震規模:🟢 芮氏 4.6

地震深度:🔴 20公里

最大震度:🔵 3級

震央位置:花蓮縣秀林鄉

緯度:24.11

經度:121.59

發布時間:2025年04月03日 02:01:48


地震速報

地點:花蓮縣吉安鄉

發生時間:2025-03-25
09:40:50

地震規模:🔵 芮氏 5.4

地震深度:🔵 40公里

最大震度:🔵 3級

震央位置:花蓮縣吉安鄉

緯度:23.92

經度:121.58

發布時間:2025年03月25日 09:41:02


此為預警系統自動上傳之資訊,準確信息請以交通部中央氣象署為主!

地震速報

地點:高雄市六龜區

發生時間:2025-03-23 12:23:37

地震規模:🟢 芮氏 4.5

地震深度:🔴 10公里

最大震度:🟡 4級

震央位置:高雄市六龜區

緯度:23.13

經度:120.69

發布時間:2025年03月23日 12:23:49


地震速報

地點:花蓮縣近海

發生時間:2025-03-22 20:48:13

地震規模:🟢 芮氏 4.6

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:花蓮縣近海

緯度:23.66

經度:121.56

發布時間:2025年03月22日 20:48:44


地震速報

地點:花蓮縣近海

發生時間:2025-03-22 20:48:12

地震規模:🟢 芮氏 4.6

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:花蓮縣近海

緯度:23.65

經度:121.6

發布時間:2025年03月22日 20:48:35


地震速報

地點:花蓮縣近海

發生時間:2025-03-22 20:48:12

地震規模:🟢 芮氏 4.5

地震深度:🔵 40公里

最大震度:🟢 2級

震央位置:花蓮縣近海

緯度:23.7

經度:121.58

發布時間:2025年03月22日 20:48:30

分類: aleart | 4 則留言

幹話語錄2 技術總結筆記

這邊就只是很簡單記錄一下我花了3天從0開始到發布的一些過程。

資料庫

Hostinger

在寫一代的時候一直有一個遺憾就是沒有串聯資料庫,所以第二代就打算讓我的幹話語錄連接到一個線上的資料庫,而在搜尋了半天後發現我的網站所使用的HOSTINGER其實就有架設SQL 資料庫的功能,那架設的方式也很簡單點選畫面中的database你就可以創造一個你自己的資料庫,創建好之後記得要到remote SSL去開放外界連接。

HOSTINGER 頁面
新增資料庫
開放連接

用 python 快速連接

然後呢我就使用Python去連接資料庫並且創一個新的table,裡面會存取 C_ID, 案讚人數,案不喜歡的人數 以及他的詳細資訊。

import pymysql
db = pymysql.connect(host=host, port=port, user=user, passwd=passwd, db=dbname)
cursor = db.cursor()
cursor.execute("""CREATE TABLE tablename (
C_ID INT AUTO_INCREMENT,
WORD TEXT,
LIKE INT,
UNLIKE  INT,
DETAIL TEXT
);""")

db.close()

接著我們就可以使用pandas去讀取我過去的幹話並且上傳上去,

資料庫

Android stduios

我手機呢則是使用Android Studio + kotlin來寫的,基本上呢我不會寫kotlin,所以一切的功能我都會直接查詢網上解答並且直接套用。

SQL

那麼剛開始我第一個要製作的功能,也是最重要的就是連接資料庫,根據我各種查詢以及嘗試,使用了三種不同SQL的Jar庫,終於成功了連上了!

之所以會試著這麼多就是沒有發現到我使用的資料庫是MariaDB,我之前面一直在嘗試使用MYSQL的套件包去連接發現不管怎麼連都連不上,千萬不要像我一樣這麼智障。

那麼連接的方式呢就是要先去下面下載這個jna.jar

https://jar-download.com/?search_box=net%20java%20dev%20jna

把下載的檔案放到libs 裡面之後,在build.gradle裡面增加下面兩行

再來就可以嘗試使用JDBC連接資料庫

var stat:Statement?=null
var resu:ResultSet?=null

private fun connectFuncSQL(): Connection? {
    val connectionProps = Properties()
    connectionProps["user"]     = user
    connectionProps["password"] = password
    Log.d("MYSQL", "Start connection")
    // connect with mariaDb
    try {
        val conn = DriverManager.getConnection(
            "jdbc:mariadb://$host:$port/dbname",connectionProps)
        Log.d("MYSQL", "connection successful")
        return conn
    } catch (ex: SQLException) {
        Log.e("MYSQL", ex.message.toString())
        ex.printStackTrace()
    } catch (ex: Exception) {
        Log.e("MYSQL", ex.message.toString())
        ex.printStackTrace()
    }
    return null
}

如果成功連上了就可以開始下載資料庫上面的資料,我會將下載好資料使用 getSharedPreferences 的存到使用者手機裡。

@SuppressLint("ApplySharedPref")
private fun updateFunc(){
    val conn = connectFuncSQL()
    try {
        stat = conn?.createStatement()
        Log.d("MYSQL", "CreateStatement")

        val gson = Gson()
        val sharedPref = getSharedPreferences("sqlDATA",Context.MODE_PRIVATE) ?: return
        resu = stat?.executeQuery("SELECT * FROM `table_name`;")
                    Log.d("MYSQL", "call table")

        var funcCidArr    : Array<Int>    = arrayOf<Int>()
        var funcWordArr   : Array<String> = arrayOf<String>()
        var funcDetailArr : Array<String> = arrayOf<String>()
        var funcLikeArr   : Array<Int>    = arrayOf<Int>()
        var funcHateArr   : Array<Int>    = arrayOf<Int>()
        runOnUiThread {
                Toast.makeText(this, "下載資料中...",Toast.LENGTH_SHORT).show()
            }
        while(resu?.next() == true){
                val funcCid    :Int    = resu?.getInt("C_Id")!!
                val funcWord   :String = resu?.getString("WORD").toString()
                val funcDetail :String = resu?.getString("DETAIL").toString()
                val funcLike   :Int    = resu?.getInt("LIKE")!!
                val funcHate   :Int    = resu?.getInt("UNKILE")!!

                funcCidArr    += funcCid
                funcWordArr   += funcWord
                funcDetailArr += funcDetail
                funcLikeArr   += funcLike
                funcHateArr   += funcHate

            }
        Log.d("MYSQL", "Writing data")
        val editor = sharedPref.edit()
        editor.putString("funcCidArr", gson.toJson(funcCidArr))
        editor.putString("funcWordArr", gson.toJson(funcWordArr))
        editor.putString("funcDetailArr", gson.toJson(funcDetailArr))
        editor.putString("funcLikeArr", gson.toJson(funcLikeArr))
        editor.putString("funcHateArr", gson.toJson(funcHateArr))
        editor.commit()
        runOnUiThread {
                Toast.makeText(this, "資料已是最新版",Toast.LENGTH_SHORT).show()
            }
        }catch (ex: Exception) {
            Log.e("MYSQL", ex.message.toString())
            ex.printStackTrace()
        }finally {
            conn?.close()
        }

   }

動畫

按鈕標題

為了讓我APP看起來更好看一點,我在許多的地方都加了一些動畫,例如打開程式時按鈕會從左邊依序往右邊跑,還有幹話語錄的”2″會由上而下的滑下來,為了做到這些我們需要寫一個自定義的XML檔

那首先這個是幹話語錄中的”2″ ,其實寫法也很簡單只需要給他初始位置終點位置然後最後是所花的時間

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:fromYDelta="-100%"
        android:duration="1800"/>

    <alpha
        android:fromAlpha="0.3"
        android:toAlpha="1.0"
        android:duration="1800" />
</set>

而至於按鈕地成左至右呢,寫法是一模一樣的,那如果要讓按鈕依序出來走我們只要改變duration的時間就好了。

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate
android:fromXDelta="-100%"
android:fromYDelta="0%"
android:duration="1000"/>
</set>

頁面切換

頁面切換的時候我也希望有動畫,可以用滑的來切換不同的頁面,這個其實也用寫XML檔來達到,只是我們需要寫兩個,一個負責處理頁面離開,一個負責處理頁面進來。

離開

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:fromYDelta="0%"
        android:toYDelta="100%"
        android:duration="200"/>
</set>

進來

<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
    <translate
        android:fromXDelta="0%"
        android:fromYDelta="-100%"
        android:toYDelta="0%"
        android:duration="200"/>
</set>

接著只要再切換頁面的時候加以下這一句就好了

override fun onBackPressed() {
        super.onBackPressed();
        overridePendingTransition(R.anim.slide_up_activity_into, R.anim.slide_up_activity_leave);
    }

幹話總覽

在開始前我們先看一下成品

可以看到這是一個清單,將所有的幹話排排列在上面,跟清單不一樣的是,他下面有按讚跟倒讚可以按,還有愛心 !

那要做到這樣子的我們需要一個自定義的adapter,用來告訴他每一行的元素該放什麼字該做什麼事情,我們還要自定義一個Layout,用來告訴他我們的文字按鈕該怎麼排列擺放。

自定義Layout

下面是我自定義的 CustonLayout.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="4dp">

    <TextView
        android:id="@+id/tvContact"
        android:layout_width="match_parent"
        android:layout_height="100dp"
        android:textSize="18sp"
        android:gravity = "center"
        android:clickable="true"
        android:textStyle="bold" />

    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="horizontal"
        android:layout_gravity = "right"
        android:padding="8dp">

        <com.like.LikeButton
            app:icon_type="thumb"
            app:icon_size="15dp"
            android:id="@+id/btn1"
            android:layout_marginStart="10dp"
            android:layout_width="50dp"
            android:layout_height="50dp"/>

        <TextView
            android:id="@+id/likeText"
            android:layout_width="wrap_content"
            android:layout_height="match_parent"
            android:layout_marginStart="10dp"
            android:textSize="30sp"
            android:layout_marginTop="5dp"
            android:gravity = "center_horizontal" />

        <com.like.LikeButton
            app:icon_type="thumb"
            app:icon_size="15dp"
            app:like_drawable = "@drawable/thumb_unlike"
            app:unlike_drawable="@drawable/thumb_off"
            android:rotation="180"
            android:id="@+id/btn2"
            android:layout_marginStart="20dp"
            app:circle_start_color="#000000"
            app:circle_end_color="#000000"
            android:layout_width="50dp"
            android:layout_height="50dp"/>

        <TextView
            android:id="@+id/hateText"
            android:layout_width="wrap_content"
            android:layout_marginStart="10dp"
            android:layout_height="match_parent"
            android:layout_marginTop="5dp"

            android:textSize="30sp"
            android:gravity = "center_horizontal" />

        <com.like.LikeButton
            app:icon_type="heart"
            app:icon_size="15dp"
            android:id="@+id/btn3"
            android:layout_alignParentRight="true"
            android:layout_marginStart="20dp"
            android:layout_gravity="right"

            android:layout_width="50dp"
            android:layout_height="50dp"/>
        <TextView
            android:id="@+id/textViewBlank"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:clickable="true"/>

    </LinearLayout>
</LinearLayout>

可以看到我的按鈕上面還有讚跟愛心,這個呢我是使用 :

https://github.com/jd-alexander/LikeButton

用法也很簡單只要先把以下文字放到setting.gradle

allprojects {
	repositories {
		...
		maven { url "https://jitpack.io" }
	}
}

然後再增加dependencies

接著你就可以在你的Layout裡面使用這個酷酷的讚跟愛心按鈕了

那他的按跟不按呢其實是使用圖片來偽裝成按下去的感覺,所以如果要改按下去後的顏色,必須在外面自己製作一個不同顏色的讚,再去更改它的drawable屬性

      <com.like.LikeButton
            app:icon_type="thumb"
            app:icon_size="15dp"
            app:like_drawable = "@drawable/thumb_unlike"
            app:unlike_drawable="@drawable/thumb_off"
            android:rotation="180"
            android:id="@+id/btn2"
            android:layout_marginStart="20dp"
            app:circle_start_color="#000000"
            app:circle_end_color="#000000"

            android:layout_width="50dp"
            android:layout_height="50dp"/>

自定義 Adapter

自定義一個adapter,我們會需要自己開一個新的class。

class MyAdapter(val context:        Activity    ,
                val funcCidArr:     MutableList<Int>   ,
                val funcWordArr:    MutableList<String>,
                val funcDetailArr:  MutableList<String>,
                var funcLikeArr:    MutableList<Int>   ,
                var funcHateArr:    MutableList<Int>) :  ArrayAdapter<String>(context, R.xml.customlayout,funcWordArr) {

override fun getCount(): Int {
        return funcWordArr.size
    }

override fun getItemId(position: Int): Long {
        return position.toLong()
    }

 @SuppressLint("ResourceType", "ViewHolder", "InflateParams", "SetTextI18n", "CutPasteId")
    override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
        val layoutInflater = context.layoutInflater
        val rowView = layoutInflater.inflate(R.xml.customlayout, null,true)
        val textPart = rowView.findViewById<TextView>(R.id.tvContact)
        val likeText = rowView.findViewById<TextView>(R.id.likeText)
        val hateText = rowView.findViewById<TextView>(R.id.hateText)

        val blackText = rowView.findViewById<TextView>(R.id.textViewBlank)
        textPart.text = funcCidArr[ position].toString() + ". "+ funcWordArr[position]
        likeText.text = numtoK(funcLikeArr[position])
        hateText.text = numtoK(funcHateArr[position])

        return rowView
}
}

上面是我程式的一個大概架構,因為我的程式中含有廣告投放,還有伺服器的連接(按讚跟倒讚),還有全部按鈕的listener,所以我這邊就把一些比較重要的show出來。

複製文字

複製文字的部分我是建一個listener,如果按如果使用者按了文字,就會將文字複製到他的剪貼簿裡。

textPart.setOnClickListener{view->
    if (funcDetailArr[position] != "None") {
                var thieDetail = funcDetailArr[position]
                if ("政治" in thieDetail) {
                    thieDetail = "\t\t"+ thieDetail.subSequence(3, thieDetail.length).toString()
                }
                showAlert(thieDetail)
            }else{
                showAlert("此幹話沒有出處")
            }

            val clipboard: ClipboardManager =
                context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
            val clip: ClipData = ClipData.newPlainText("func_say", funcWordArr[position])
            clipboard.setPrimaryClip(clip)
//            toast?.cancel()
//            toast = Toast.makeText(context,"已複製進剪貼簿", Toast.LENGTH_SHORT)
//            toast?.setGravity(Gravity.BOTTOM,0,0)
//            toast?.show()
        }

showAlert

showalert是負責處理當使用者按下文字之後跳出的彈出視窗

fun showAlert(string: String){

    val dialog: AlertDialog = object : AlertDialog(context, R.style.CustomDialog) {
        override fun dispatchTouchEvent(event: MotionEvent): Boolean {
            dismiss()
            return false

        }
    }
    dialog.setMessage(string)
    dialog.setCancelable(true)
    dialog.show()
    
}

其中 dispatchTouchEvent 是用來處理使用者只要點任一的地方都會將這個彈出視窗關閉。

按讚功能

按讚功能,按下去的瞬間會將手機端的按讚人數加一,並且同時跟資料庫講這個數字要加一,所以這些按讚並不是實時更新的,而是會等到下次你打開APP時才會更新。

"""UPDATE `table_name` SET $Label = $Label $operator 1 WHERE C_ID = $id;"""

Adapter 使用

Adapter 的使用也其實很簡單只要告訴ListView就好了

val mList: ListView = findViewById<ListView>(R.id.listview)
val customAdapter = MyAdapter(
            this,
            funcCidArr,
            funcWordArr,
            funcDetailArr,
            funcLikeArr,
            funcHateArr
        )
mList.adapter = customAdapter

上架

上架期實也很簡單,先打包,打包的時候他會請你做一個金鑰那其實按照他的步驟做就可以了,打包完之後呢,我們需要開通Google Play Console的開發者資格需要25美金,但只要開通一次就好了。

先打包

點擊建立應用程式

然後把該打的打,把勾的勾,該填的填,按下確認鍵就好了。

左邊滑到底有一個應用程式內容,記得要將裡面的東西都完成,才有辦法發佈你的APP。

而這個隱私權政策,則會需要你提供一個隱私權網址,這個網址是我用以下https://app.privacypolicies.com/wizard/privacy-policy 生成的

最後在正式版裡面建立一個新版本,上傳完之後,等待Google審核,審核成功,你的APP就成功發佈出去了。

分類: Uncategorized | 發佈留言

天常M抽卡模擬

https://www.4gamers.com.tw/news/detail/50223/dinter-lineage-m-dispute

最近實況主丁特在天堂m中砸了200萬抽鑽抽紫布,前前後後進行475次製作,但只成功11次,比官方所宣布的10%還低上許多,丁特認為這樣的製作機率跟官方公告的「所有商城機率與韓版一致」有所落差,進而向消保會提出申訴,要求遊戲橘子針對機率一事給出回應。

這到底是丁特臉黑還是遊戲橘子是有問題的呢? 所以我決定針對抽卡這件事情來做模擬。

這邊我使用的程式是 Julia + Jupyter

首先是抽卡的程式,times 決定了抽卡的次數(例如這裡就是475次),prob就是抽到紫布的機率(這裡是10%),在這裡抽卡的方式就是從0~1隨機選一個數字,如果這數字小於prob代表抽到了,如果大於則沒有,而最後他會給我們這次抽卡的機率 (例如丁特就是 11/475,抽卡475次成功11次)。

測試幾次看看

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-16.png

可以看到機率大部分都在10%附近。

測試1千萬次看看

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-17.png

這張圖是抽卡機率的分布圖(Histogram),x軸是機率,y軸是機率的密度分布(次數除以寬度),基本上密度越高,代表出現的次數越多,你可以看到10%附近的數值是最大的。

通常這種分佈,我們都可以使用一個高斯分布去做fitting(在某些情況下有可能是卜瓦松分布),μ代表的是平均,σ則是標準差,你可以看到 μ 的數值非常的接近10%。

既然已經有抽卡的分布曲線,我們可以去思考 2.3% 是在幾個標準差之外。

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-18.png

答案是 5.57個標準差。

在統計學中, 1.645 個標準差代表著是 95% C.L(confidence level 信心水準),所以基本上 5.57 比 1.645 多了3.895個標準差,可以說發生的機率非常的小,那實際上 5.57個標準差對應的機率是多少呢 ?

如果要計算機率,我們可以使用累積分布函數(Cumulative Distribution Function),我們可以經由這個函數知道要在這個模型中獲得 “2.3%”成功率的機率是多少。

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-19.png

可以看到,如果使用平均是10,標準差是1.38的模型下,成功率是2.3%的機率大概是

1億分之一!!!!


https://forum.gamer.com.tw/C.php?bsn=25908&snA=48280

後來也有人說台服的機率是 5% 而不是 10%。

OK阿,我們就在做一次模擬。

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-20.png

可以看到分布的平均確實移動到5%囉。

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-21.png

約為2.7個標準差

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-22.png

在平均是5%的情況下,成功率為2.3%的機率是 千分之3,你說這機率高嗎?不高,除非是衰到不行的人,不然這個機率其實是不太可能的,2.7 個標準差 也比 1.645 個標準差高了1.1個標準差了,可以說是不太可能了。

結論

在官方公布機率為10%,475次中只成功了11次的機率,2.3%確實有點低,若以5%的成功率來看, 475次中只成功了11次的機率仍然為 0.3%,機率還是非常的低,低於 95% 信心標準許多,如果沒有其他外力因素,可以認為與官方公告的機率不一致。

分類: Uncategorized | 標籤: , | 發佈留言

How to develop your python package ?

pip is a software package management system written in the Python computer programming language. It can install and manage software packages, with a simple command “pip”, you can get access to more then one hundred thousand of cool libraries, here I am going to show you how to upload your own code to PyPi and able to download with pip.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-1024x467.png

There are few step for you to develop your own package.

  1. Prepare your code.
  2. Create a PyPi account.
  3. Prepare the files PyPi needs.
  4. upload it to PyPi
  5. pip install your package.
  6. Upload it to github

Code

In here, I want to upload the class I wrote for research in the institute, If you are interested, It is a code for calculate the limit of TASEH(Taiwan Axion Search Experiment Haloscope).

https://github.com/OuYangMinOa/ou_Axion_limit

This code have two class in two different File

  • class Glimit in GLimit.py
  • class analyse in Analy.py

PyPi account

Create a PyPi account for us to upload our package,

https://pypi.org/account/register/

Prepare the files PyPi needs.

Now, I wish my classes are all in a same package call ou_Axion_limit

# my expectation
from ou_Axion_limit import Glimit
from ou_Axion_limit import analyse 

so first create a folder (Glimit), this folder will content every thing PyPi needs, and next create a floder name with your package name (ou_Axion_limit ), inside the folder you just created, and throw you python code inside.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-3.png

__init__.py

Creata a file __init__.py inside the ou_Axion_limit

This file allows you to determine the classes that users can directly call and use, so in my cases, I can just import my class with following way.

# my expectation
from ou_Axion_limit import Glimit
from ou_Axion_limit import analyse

setup.py

The setup.py file contains the information that PyPi needed , such as its name, description, current version, etc. Copy and paste the following code and replace the string with the matching content:

CHANGELOG.txt

The changelog of you package

LICENSE.txt

Use this file to define all license details, you can use your own license, however, I will use MIT license

MANIFEST.in

Just a file use to include everything

README.md

A markdown file can make people understand your package better.

Upload it to PyPi

Everything is prepared, we can now upload it to PyPi.

First, goto you folder open cmd and tpye:

python setup.py sdist
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-4-1024x613.png

If you see UserWarning: Unknown distribution option: ‘install_requires’, just ignore it.

It should create a file in dist folder

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-6.png

Next, we need twine for upload the package

pip install twine

Then, run the following command:

twine upload dist/{Generated_file}

You will be asked to provide your username and password. Provide your credentials you used to register with PyPi.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-7-1024x160.png

Congratulations, you successfully upload your packge to the PyPi, goto the website it gives you to see your package online.

Install your package

pip install YOURPACKAGENAME
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-8-1024x487.png

Upload to github

For the fist time using git, we need to create a ssh-key to connect to github

ssh-keygen
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-10-1024x223.png
I create a ssh key in C:\Users\USER/.ssh/

It did exist.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-11.png

Show the content

type filename
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-12.png

Copy everything and add in to your account.

https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account

Create your repository

Then upload your project.

git init
git add .
git commit -n "first upload"
git remote add origin git@github:{name/project}
git push -u origin master

If you want to upload new code later, you only need to type the following commands.

git add .
git commit -m "v1.0.0"
git push
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-15.png
分類: Uncategorized | 標籤: , | 發佈留言

SSH to a Linux by ngrok and manipulate existing terminal

In http://ouyangminwei.com/index.php/2021/09/18/build-a-discrod-music-bot/, I created a discord bot and develop on a Raspberry pi, but now there are two problems

  1. The network used by is a floating IP.
  2. Even if I can SSH in, I still can’t see or close the discord bot since It is on a terminal.

Ngrok

After searching a little bit, I found that ngrok can solve the first problem perfectly.

Ngrok is a cross-platform application that exposes local server ports to the Internet, so I can expose my raspberry pi to the internet.

First, sign up and download ngrok on this website https://ngrok.com/.

Because it runs on the Raspberry Pi, so download the 32-Bit ARM’s version

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-39.png

After you download the ngrok upzip it.

unzip ngrok-stable-linux-arm.zip.zip
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-38.png

Login the ngrok, yo can get your Authtoken

./ngrok authtoken
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-37-1024x556.png

And you are ready to fire it up.

./ngrok tcp 22
解析Ngrok 曲折的攻擊程序– 資安趨勢部落格

remember the Ip it gives you

tcp://2.tcp.ngrok.io:14139

Then you can SSH to it

ssh username@2.tcp.ngrok.io -p14139
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-41.png

Screen

In order to access to running terminal, we can use “screen” to achieve it

sudo apt-get install screen
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-40.png

This can create a new screen call “bot”

screen -mS bot

And you can start your server, for here, I will test will python httpserver

python -m SimpleHTTPServer
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-42.png

Now, the server is running, CTRL+A and then CTRL+D to detach the screen.

screen -ls

Show the screen

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-43.png

I have a “test.root” over here, Try to see if I can download this file via this python http server

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-44.png
wget 127.0.0.1:8000/test.root
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-45-1024x183.png

Every works well, the server it still running.

screen -x bot

Back to the terminal

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-46.png

So now, I can access the Raspberry pi with ngrok and use screen to control the terimal.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-47.png
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-48-1024x157.png

分類: Uncategorized | 標籤: , | 發佈留言

Build a discrod music Bot

https://www.theverge.com/2021/8/24/22640024/youtube-discord-groovy-music-bot-closure

這張圖片的 alt 屬性值為空,它的檔案名稱為 99nShh7.png

https://www.theverge.com/2021/9/12/22669502/youtube-discord-rythm-music-bot-closure

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-20.png

Recently, youtube kill’s some of the most used music robots on discord, and other public ones may also be asked to be shut down, so today let us make our discord bot!!!

Step 1 : Create your bot

Goto this website https://discord.com/developers/applications, I have already created one, click the “New Application” button.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-22-1024x480.png

And name your bot.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-23.png

If you create the bot successfully, you should see it appear on your main page, just click it.

Go and copy your APPLICATION ID, and fill in this link:

https://discordapp.com/oauth2/authorize?&client_id=xxxxxxxxxxxxx&scope=bot&permissions=8 # replace xxxxx with you Id
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-25-1024x570.png

with this link, you can invite it to your channel.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-27-1024x568.png

Step 2 : authorization token

Go to the “bot” and click “copy”, this will give you your Token

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-24-1024x615.png

Step 3 : Start coding

Here, I’m will build the bot with python in windows, so you will need python on your computer

open cmd and download discord’s API

pip install discord.py
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-28-1024x436.png

Open sublime and paste the following code to start a simple bot

save and open with cmd.

we know this is not enough…, we need a music bot, not a ping-pong idiot…, next, I will speed up and point out the difficulties and solutions I encountered.

Step 4 : A music bot

A normal music bot should be able to play youtube music and have the following functions.

  • play : Add a song or a playlist to the Queqe and invite the bot to the voice channel
  • pause : pause
  • skip : skip current song
  • list : show the playlist
  • clear : clear the playlist
  • loop : loop the playlist
  • leave : leave the voice channel

we define severals function that we want our music bot have.

Step 5 : Play a music

Let’s see how others play music

with this code we can understand how everything works, first, we need FFmpeg.

https://www.ffmpeg.org/download.html

when a user types a play command, the code will get its message channel (ctx), and get the Author’s voice channel (channel), then with “channel.connect()” to connect the bot to the voice channel.

channel = ctx.message.author.voice.channel #this line will get the user's voice channel
voice =  await channel.connect()   # connect to the user's voice channel

voice.play(discord.FFmpegPCMAudio(song_path), after = lambda e: somefuciton())
# play the music ,  'after' will run when the song is finish.

Step 6 : Create a class

you may ask: why do we need a class?

If our robot is to serve different servers, it means that there will be different ctx, channel, and voice, we also need to queue the songs of each channel, so the best choice is to create a class, each class serves a server.

class MusicBot:
    def __init__(self,channel, voice , ctx):
        self.music_msg = None       # The message for current music
        self.loop      = False      # Enable loop or not
        self.live      = True       # Kill this Musicbot if self.live = False
        self.channel   = channel    # Voice channel
        self.channelid = channel.id # This Music serves channel Id
        self.floder    = "music"    # Folder to store music
        self.ctx       = ctx        # ctx
        self.voice     = voice      # voice client
        self.queqed    = []         # music queqed for play
        self.passed    = []         # Played music
        self.state     = 0          # 0:not playing , 1:playing , 2:pause
        self.rejoin_c  = 0          # rejoin every 20 songs
        self.dont_stop = 0          # will play untill dont_stop = 3 to check again

so I define a class that needs channel, voice, and ctx as input.

Step 7 : Download youtube music

we know we can use youtube_dl to download the music.

pip install youtube-dl
self.ytl  = {
                'format': '249/250/251',
                "outtmpl" : f"{self.floder}/{this_song_name}",
                'noplaylist': False
} 
with youtube_dl.YoutubeDL(self.ytl) as ydl:
    ydl.download([this_song_url])

But I think it is difficult to manage which songs the user has queued and youtube_dl will download the entire playlist before I play the music, of course, I can use a thread, But it is too complex.

So, I will use a youtube data API to grab the playlist’s songs and download one at a time and play it. the following is the youtube API code, however, I will not explain this code since our main character is a discord music bot.

with this API, I can write a function to add music to the queue

def add_thread(self,url):
        print("[*] Adding rest in this thread ... ")
        output = grab_playlist(url,50)
        for each in output[10:50]:
            self.queqed.append(each)
        print("[*] Adding Thread done.")
        print(f"[*] Qeuqed {len(self.queqed)} songs ->",self.channelid)

async def add(self,url):
        print("[*]", url)
        if ("list" in url):
            print("[*] Adding a play list in", self.channelid)
            output = grab_playlist(url,10)
            for each in output[0:10]:
                self.queqed.append(each)
            threading.Thread(target = self.add_thread, args=(url,)).start()

        else:
            print("[*] Adding a single video in", self.channelid)
            self.queqed.append((get_title(url),url))

        print("\n[*]",self.channelid,"-> Enqueued :",len(self.queqed), "the remaining songs will continue add in the background")

        if (self.state ==0):
            self._next()  #  the play music function

add function can handle a video or a playlist, if it is a video, just add it directly, but if it is a playlist, I will first grab the first 10 videos, the rest will throw in a thread to continue, this is to speed up the time to start the song, otherwise, the user will feel impatient.

Play command

Users_class  = {}

@client.command(brief="Play music (My wonderful singing )")
async def play(ctx, url : str):
    if not ctx.message.author.voice:
        await ctx.send('you are not connected to a voice channel')
        return
    else:
        channel = ctx.message.author.voice.channel

    if (channel.id in Users_class):
        if ctx.guild.voice_client not in client.voice_clients:
            await Users_class[channel.id].kill() # kill the music player
            del Users_class[channel.id]
            print("[*] rejoin the voice channel")
            voice =  await channel.connect()
            MB = MusicBot(channel, voice , ctx)
            Users_class[channel.id] = MB
        await Users_class[channel.id].add(url)
    else:
        voice =  await channel.connect()
        MB = MusicBot(channel, voice , ctx)
        print(f"[*] creating Class id : {id(MB)} for serving channel",channel.id)
        Users_class[channel.id] = MB
        await MB.add(url)

In play command, I will create the music bot class and save the class to a dictionary by using channel id as the key.

# play next music
async def _next(self):

    if (len(self.queqed) == 0):

        if (self.loop): # refill the music queqed for play with Played music
            self.queqed = self.passed
            self.passed = []
        else:
            self.state = 0
            return    

    self.state = 1    # State = 1 -> start playing                 
    self.this_song  = self.queqed.pop(0) # get the song 
    self.passed.append(self.this_song)   # Store in history music

    print("[*] playing  :", self.this_song[0],"in", self.channelid)
    this_song_url   = self.this_song[1]
    this_song_name  = self.this_song[0]


    #  This for is beacuse the youtube_dl will change the filename
    #  when handling special char
    for each_char in ['"', "'", ":", "|"]:
        if (each_char in this_song_name):
            this_song_name = this_song_name.replace(each_char,"#")

    # youtube_dl will create a floder for \ and /
    for each_char in ["\\", "/"]:
        if (each_char in this_song_name):
            this_song_name = this_song_name.replace(each_char,"")

    song_path  = os.path.join(self.floder , this_song_name)

    # download youtube music
    if ( not os.path.isfile(song_path)):
        self.ytl  = {
            'format': '249/250/251',
            "outtmpl" : f"{self.floder}/{this_song_name}",
            'noplaylist': False,
        } 
        self.dowloading = await self.ctx.send(f'... Downloading {this_song_name}')
        print("[*] downloading ->", this_song_name,"\n")
        with youtube_dl.YoutubeDL(self.ytl) as ydl:
            ydl.download([this_song_url])
        print("\n[*] ------------ download successful ------------")

    # Check if bot is in the voice channel
    if self.ctx.guild.voice_client not in client.voice_clients:
        print("[*] get kicked from",self.channelid)
        return

    # send currently playing music
    self.music_msg = await self.ctx.send(f':musical_note:  Now playing ({len(self.passed)}/{len(self.queqed)+len(self.passed)}) : {this_song_name} :musical_note:')

    

    ######################   I will explian this later
    FFMPEG_OPTS = {
        'before_options': '-reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 5', 
        'options': '-vn'
        }
           self.rejoin_c += 1
   if (self.rejoin_c == 10):
         self.voice.play(
                discord.FFmpegPCMAudio(song_path, **FFMPEG_OPTS), 
                after=lambda e: print("[*] reconnecting the ffmpeg , error : ",e)
                )
        self.rejoin_c = 0

        await asyncio.sleep(5)
   ######################

    # play the music, call _endsong when the song finish
    self.voice.play(
            discord.FFmpegPCMAudio(song_path), 
            after = lambda e: asyncio.run_coroutine_threadsafe(self._endsong(e), client.loop)
            )

    
    # check every three song 
    self.dont_stop +=1
    if (self.dont_stop > 3):
        client.loop.create_task(self.check())


This is a quite long function, but most of them are actually pretty easy to understand, except the FFMPEG_OPTS part, this part is to solve a known problem.

https://support.discord.com/hc/fr/articles/360035010351–Known-Issue-Music-Bots-Not-Playing-Music-From-Certain-Sources

The robot will suddenly have no sound while playing a song, I often encounter this problem when I am testing,

To solve this problem, you have to use that FFMPEG_OPTS variable. It will reconnect the bot to the source.

But there is a bug, I’m not sure if it is my problem or how, my FFmpeg will show “reconnect” Option not found, I still trying to fix it.

Step 8 : Complete every thing

This is my MusicBot with all the functions we want.

Then try to run the bot and see if everything works well.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-29.png

Step 9 : Develop on server

Now try to put this robot on a server, you can use Heroku or something else, for me , I will put it on the Raspberry Pi

這張圖片的 alt 屬性值為空,它的檔案名稱為 dwzZ6giNPkhGbmumGqcT1PEHXUM6vGh4-KH6_DN6_W43eWgqiB8m7VIbTTmKkWdaTemgixIxJypIOTqtoiBrsGcG7nSMipYBg5k67A-0w4ft3BqpL_HRGePRdXz01S3euElu2lizy2EdfJV1iNwZ5fAT34kkylwHbI3wvwEoJZTZB8bKwSYWvw1YKUJ_qflXvbUVhjiBiQ6MBd95jHfg45hgcuPJSYYmw9UaGIPFTeUGzem7IT7AttdDi15Y3EeRxWd-ljVAurT4kifjwQ73j807SordCQY8M4Znj-xWB-22sS0CsqHsD3-t8QtbDNM8q95K0Y-vAM_X1ZaYIMs1lphaauKtIzhYAYtBsa_uSLwxEWVpFwUz6e5bPm2_mJnIylvd2h3W_qbUH9iltC3B9NVDO1_UBmOTqeS3l7q6l0lUjbGoe7ogyNwILFaFku_Cb9Je9lmhwqkkjvNfk7vqRjgzwJdU9kCWqsR8PBtPXIpCfuap6rxJ0OLem-89UQBtSetp5tZSvwbtvhXEMlRLHzOWBnKJ5QB7gZbng7n_MN84NyudLsFQZF4bRIJ3zLG-zTZFjzCmg3AtlZsdc_yGH8itL_B7C_693uM31TZvk-F47ZM5oD37Q5bP1hMBwe6_ntYX1vnKpKfwHa-5Ro0JXL1Nr_I7FY16IpCu2FGJ9JVQav8-XMGOpQhrbyMyeAihJSVTiy8GRk8lYFU3eAzCJrQ=w678-h903-no

So, first I will use python to open a simple webserver on windows to send my bot’s code to Raspberry Pi .

python -m http.server
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-30.png

Cause I’m connect to the same route, so I can use the local internet to send my bot, use Ip config to get you computer’s local IP

ipconfig
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-35.png

Just wget the ip: port/file and you can grab the file

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-31-1024x535.png

Set up your environment and run the server

pip install google-api-python-client
pip install discord.py
pip install youtube_dl
sudo apt install ffmpeg
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-32-1024x268.png

Congratulations, you successfully made your own robot !!!

分類: Uncategorized | 標籤: , | 發佈留言

How to solve pip not found

This is because pip has not been added to the path

So first, follow my step to find python’s floder.

這張圖片的 alt 屬性值為空,它的檔案名稱為 2021-09-16-edited.png
這張圖片的 alt 屬性值為空,它的檔案名稱為 2021-09-16-5-1024x610.png
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-13-1024x607.png

so this is my python floders

C:\Users\wesle\AppData\Local\Programs\Python\Python37     # This is python
C:\Users\wesle\AppData\Local\Programs\Python\Python37\Scripts   # This is pip

Then open the setting of environment variables, for English users, try ‘env’.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-14-1024x841.png
Screenshot of Start Search
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-15.png
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-16.png

Add the floder path we Just get

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-17.png

Open cmd and type pip, your path is set up right now.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-18-1024x513.png
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-19-1024x303.png
分類: Uncategorized | 標籤: , | 發佈留言

How to download python in windows and run with Jupiter and sublime.

why python? Python is a programming language that lets you work more quickly and integrate your systems more effectively. <– (Introduction on the official website), and also my favorite language.

Here, I will show how to download python and run with Jupiter and Sublime

Goto https://www.python.org/, click download, windows

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-1024x599.png

Choose you version, for me, I will download python 3.7 (64bit)

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-1-1024x720.png

open the installer, remember to Check Add Python3.* to PATH, and Just click Install Now.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-3.png

Download Sublime, https://www.sublimetext.com/

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-4-1024x448.png

Click next and install it.

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-5.png

Fisrt program

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-6.png

CTRL + SHIFT + P type python, and save the file and with .py

CTRL + B to run the code

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-7-1024x873.png

Install Jupyter

Windows + R and type CMD

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-8.png

If the python’s installation is correct, pip should show something, if you did not see it, try to fix it with following url.

http://ouyangminwei.com/index.php/2021/09/16/how-to-solve-pip-not-found/

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-9-1024x590.png

Pip is a python package manager, you can type ‘pip install notebook’ to install Jupyter.

pip install notebook

And type ‘jupyter notebook’ to start the jupyter notebook

jupyter notebook
這張圖片的 alt 屬性值為空,它的檔案名稱為 image-10-1024x349.png

It will open a web page, press new and select python3 to start a new script

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-11-1024x382.png

And you start your coding

這張圖片的 alt 屬性值為空,它的檔案名稱為 image-12-1024x260.png

Commonly used Jupyter shortcut keys

Function short key
Show all the shortcutH
command modeEsc
edit modeEnter
Save notebooks
Create a new cell abovea
Create a new cell belowb
delete celldd
undoz
run the current cell, select belowShift + Enter
run selected cellsCtrl + Enter
Alt + Enterrun the current cell, insert below
分類: Uncategorized | 標籤: , | 發佈留言

Lyto-Different-Color Plug-in

Lyto-Different-Color It’s basically a simple color recognition game, when I saw this game for the first time, I had the idea of using python and opencv to write this game assistant.

so first we need python, If you don’t know how to download python, you can go to this page

http://ouyangminwei.com/index.php/2021/09/13/how-to-download-python-in-windows/

We need opencv and pillow for image processing, numpy for array and mss for screenshot.

pip install numpy
pip install opencv-python
pip install pillow
pip install mss==2.0.22

Next, we need to get the game screen

# select screen range
mon = {'top': 179, 'left': 706, 'width': 1214-706, 'height': 1080-179}

sct = mss()
sct.get_pixels(mon)

while True:
    # transform the screen information to numpy array
    img = np.array(Image.frombytes('RGB', (sct.width, sct.height), sct.image))

    # show the screen via opencv
    cv2.imshow('test', np.array(img))
    if cv2.waitKey(25) & 0xFF == ord('q'):
        cv2.destroyAllWindows()
        break

I want the program to find the ball in the screen first, and then get the color of the center of the ball, so that it can find the ball with a different color, there is a funcction in opencv, call HoughCircles, it can help us to find the circle in the image.

The usage is very simple, just throw the image into the function, well… and some parameters

# transform the image into gray scale to speed up the calculation
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Houghcircles
circles = cv2.HoughCircles(gray, cv2.HOUGH_GRADIENT,1.2,10)

# circles will be something likes 
# [(x1, y1, r1),(x1, y1, r1) ...]
# where x1 y1 is the position of circle's center and r is the radius

with circle’s center, we can get correspondging color

color = []
# loop every circle
for (x, y, r) in circles:
    # store the circle's center color into 'colors'
    colors.append(list(img[y,x,:]))

I write a function to find the different one, (there must be a better way of writing, but I only use a very dumb way)

def find_different(arr):
    for num,i in enumerate(arr):
        if (arr.count(i)==1):
            return num
    else:
        return 0

At this point, we are done. All we need is to put them all together and draw the balls of different colors.

Let’s take a look at the results

Github : https://github.com/OuYangMinOa/Lyto-Different-Color

分類: Uncategorized | 標籤: , , | 發佈留言