Linux中國

使用 tqdm 在 Python 應用中顯示進度

阿拉米語,希伯來語和阿拉伯語中的閃米特語根 q-d-m 通常與前進或進度有關。阿拉伯語 taqaddum (تقدّم)的意思是「進度」。進度是很重要的。正如每部感覺良好的電影都會告訴你,旅程和目的地同樣重要。

大多數程序都有一個明確的目標,一個期望的最終狀態。有時,計算這個最終狀態可能需要很長的時間。雖然計算機沒有感情不在乎,但人卻在乎。人類並不樂意坐在原地等待,而看不到任何明顯的進展跡象。疑問不斷蔓延。程序崩潰了嗎?磁碟性能是否抖動?操作系統是否把所有的計算資源都分配給了其他任務?

就像正義一樣,進度必須被看到,而不僅僅是完成。Pythontqdm 有助於使進度變得明確。

tqdm 模塊可在控制台下工作,但它也專門支持了我最喜歡的環境之一 Jupyter。要在 Jupyter 中使用 tqdm,你需要導入 notebook 子模塊並安裝 ipywidgetsnotebook 子模塊與 tqdm 介面兼容。

這意味著你可以做一些導入時操作來導入正確的模塊,同時保持 tqdm 的用法不變。訣竅是檢查 __main__ 模塊是否具有全局變數 get_ipython。雖然這只是一個啟發式的方法,但卻是一個相當準確的方法:

import sys
if hasattr(sys.modules["__main__"], "get_ipython"):
    from tqdm import notebook as tqdm
else:
    import tqdm

最簡單的情況是,某件事情需要運行一定的迭代次數(事先已知),而每一次迭代的時間都差不多。例如,有一個計算任何數字的平方根的演算法,通過從 1 作為猜測值開始,然後計算出一個改進後的猜測值:

def improve_guess(rt, n):
    return (rt + n/rt) / 2

一點點的改進可以讓你更加接近該平方根。例如,你可以計算 2 的平方根:

guess = 1
target = 2
for i in tqdm.trange(10):
    guess = improve_guess(guess, target)

![tqdm output](/data/attachment/album/202101/06/230856gxlbiwlifuwpwxnz.png "tqdm output")

精確了到小數點後 10 位!

round(2 - guess*guess, 10)
0.0

一個稍微複雜一點的例子是,當元素的數量是已知的,而處理每個元素需要類似的時間。例如,你可以計算一些數字的乘積。為此,你需要一些隨機數:

import random
numbers = [random.uniform(0, 2.8) for i in range(100)]
numbers[:5]
[2.6575636572230916,
0.1286674965830302,
1.0634250104041332,
1.1760969844376505,
0.45192978568125486]

現在有了這些數字,可以將它們相乘了。使用 tqdm 最簡單的方法是包裝一個 Python 迭代函數。數值是一樣的,但是 tqdm 會顯示一個進度條:

result = 1
for num in tqdm.tqdm(numbers):
    result *= num
result
2.4081854901728303

![tqdm output](/data/attachment/album/202101/06/230856i67kxl5l6lp3txcz.png "tqdm output")

然而,並不是所有的事情都可以預測。最不容易預測的事情之一就是網路速度。當你下載一個大文件時,衡量進度的唯一方法就是檢查已經下載了多少:

url = "https://www.python.org/ftp/python/3.9.0/Python-3.9.0.tgz"
import httpx
with httpx.stream("GET", url) as response:
    total = int(response.headers["Content-Length"])
    with tqdm.tqdm(total=total) as progress:
        for chunk in response.iter_bytes():
            progress.update(len(chunk))

![tqdm output](/data/attachment/album/202101/06/230856e9hzma2muf01fd06.png "tqdm output")

有時,「嵌套」進度條是有意義的。例如,如果你要下載一個目錄,你就需要一個進度條來跟蹤文件,並為每個文件設置一個進度條。

下面是一個例子(但沒有實際下載一個目錄):

files = [f"vid-{i}.mp4" for i in range(4)]
for fname in tqdm.tqdm(files, desc="files"):
    total = random.randrange(10**9, 2 * 10**9)
    with tqdm.tqdm(total=total, desc=fname) as progress:
        current = 0
        while current < total:
            chunk_size = min(random.randrange(10**3, 10**5), total - current)
            current += chunk_size
            if random.uniform(0, 1) < 0.01:
                time.sleep(0.1)
            progress.update(chunk_size)

![tqdm output](/data/attachment/album/202101/06/230856dxa555yt3on0v72u.png "tqdm output")

所以,如果你的程序需要一段時間才能顯示最終結果,為避免讓你的用戶感到沮喪。請顯示它的進度!

via: https://opensource.com/article/20/12/tqdm-python

作者:Moshe Zadka 選題:lujun9972 譯者:geekpi 校對:wxy

本文由 LCTT 原創編譯,Linux中國 榮譽推出


本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive

對這篇文章感覺如何?

太棒了
0
不錯
0
愛死了
0
不太好
0
感覺很糟
0
雨落清風。心向陽

    You may also like

    Leave a reply

    您的電子郵箱地址不會被公開。 必填項已用 * 標註

    此站點使用Akismet來減少垃圾評論。了解我們如何處理您的評論數據

    More in:Linux中國