當前位置:
首頁 > 知識 > 每天用 Jupyter寫5 分鐘的日記|Linux 中國

每天用 Jupyter寫5 分鐘的日記|Linux 中國

導讀:用 Jupyter 和 Python 在你的日常寫作背後實現一些自動化。                 

本文字數:4400,閱讀時長大約:5分鐘

https://linux.cn/article-12887-1.html

作者:Moshe Zadka

譯者:Xingyu.Wang

有些人會遵循傳統,制定一年的計劃。不過,一年的時間很長,所以我以季節性的主題或軌跡來規劃。每個季度,我都會坐下來,看看即將到來的三個月的季節,並決定在這段時間裡我將努力做什麼。

對於我最新的主題,我決定要每天寫一篇日記。我喜歡有明確的承諾,所以我承諾每天寫 5 分鐘。我也喜歡有可觀察的承諾,哪怕只是對我而言,所以我把我的記錄放在 Git 里。

我決定在寫日記的過程中實現一些自動化,於是我使用了我最喜歡的自動化工具:Jupyter。Jupyter 有一個有趣的功能ipywidgets,這是一套用於 Jupyter Notebooks、JupyterLab 和 IPython 內核的互動式 HTML 組件。

如果你想跟著本文的代碼走,請注意,讓你的 JupyterLab 實例支持組件可能有點複雜,請按照這些說明來進行設置。

導入 ipywidgets 模塊

首先,你需要導入一堆東西,比如 ipywidgets 和Twisted。Twisted 模塊可以用來創建一個非同步時間計數器:

import twisted.internet.asyncioreactor

twisted.internet.asyncioreactor.install()

from twisted.internet import reactor, task

import ipywidgets, datetime, subprocess, functools, os

設置定時條目

用 Twisted 實現時間計數器是利用了task.LoopingCall。然而,結束循環調用的唯一方法是用一個異常。倒計時時鐘總會停止,所以你需要一個自定義的異常來指示「一切正常;計數器結束」:

class DoneError(Exception):

? pass

現在你已經寫好了異常,你可以寫定時器了。第一步是創建一個ipywidgets.Label的文本標籤組件。循環使用divmod計算出分和秒,然後設置標籤的文本值:

def time_out_counter(reactor):

label = ipywidgets.Label("Time left: 5:00")

current_seconds = datetime.timedelta(minutes=5).total_seconds()

def decrement(count):

nonlocal current_seconds

current_seconds -= count

time_left = datetime.timedelta(seconds=max(current_seconds, 0))

minutes, left = divmod(time_left, minute)

seconds = int(left.total_seconds())

label.value = f"Time left: {minutes}:{seconds:02}"

if current_seconds < 0:

raise DoneError("finished")

minute = datetime.timedelta(minutes=1)

call = task.LoopingCall.withCount(decrement)

call.reactor = reactor

d = call.start(1)

d.addErrback(lambda f: f.trap(DoneError))

return d, label

從 Jupyter 組件中保存文本

下一步是寫一些東西,將你輸入的文字保存到一個文件中,並提交到 Git。另外,由於你要寫 5 分鐘的日記,你需要一個能給你提供寫字區域的組件(滾動肯定是可以的,但一次能看到更多的文字就更好了)。

這就用到了組件Textarea,這是一個你可以書寫的文本欄位,而Output則是用來給出反饋的。這一點很重要,因為git push可能會花點時間或失敗,這取決於網路。如果備份失敗,用反饋提醒用戶很重要:

def editor(fname):

? textarea = ipywidgets.Textarea(continuous_update=False)

? textarea.rows = 20

? output = ipywidgets.Output()

? runner = functools.partial(subprocess.run, capture_output=True, text=True, check=True)

? def save(_ignored):

? ? ? with output:

? ? ? ? ? with open(fname, "w") as fpout:

? ? ? ? ? ? ? fpout.write(textarea.value)

? ? ? ? ? print("Sending...", end="")

? ? ? ? ? try:

? ? ? ? ? ? ? runner(["git", "add", fname])

? ? ? ? ? ? ? runner(["git", "commit", "-m", f"updated {fname}"])

? ? ? ? ? ? ? runner(["git", "push"])

? ? ? ? ? except subprocess.CalledProcessError as exc:

? ? ? ? ? ? ? print("Could not send")

? ? ? ? ? ? ? print(exc.stdout)

? ? ? ? ? ? ? print(exc.stderr)

? ? ? ? ? else:

? ? ? ? ? ? ? ?print("Done")

? textarea.observe(save, names="value")

? return textarea, output, save

continuous_update=False是為了避免每個字元都保存一遍並發送至 Git。相反,只要脫離輸入焦點,它就會保存。這個函數也返回save函數,所以可以明確地調用它。

創建一個布局

最後,你可以使用ipywidgets.VBox把這些東西放在一起。這是一個包含一些組件並垂直顯示的東西。還有一些其他的方法來排列組件,但這足夠簡單:

def journal():

? date = str(datetime.date.today())

? title = f"Log: Startdate {date}"

? filename = os.path.join(f"{date}.txt")

? d, clock = time_out_counter(reactor)

? textarea, output, save = editor(filename)

? box = ipywidgets.VBox([

? ? ? ipywidgets.Label(title),

? ? ? textarea,

? ? ? clock,

? ? ? output

? ])

? d.addCallback(save)

? return box

biu!你已經定義了一個寫日記的函數了,所以是時候試試了。

journal()

Jupyter journal

你現在可以寫 5 分鐘了!

via:https://opensource.com/article/20/11/daily-journal-jupyter

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

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

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!


請您繼續閱讀更多來自 Linux中國 的精彩文章:

據傳 SUSE 將進行 IPO,高達 60 億美元|新聞拍一拍
英國註冊機構要求公司停止使用包含 HTML 結尾標籤的公司名|新聞拍一拍