用 Jupyter 和 Python 在你的日常写作背后实现一些自动化。
有些人会遵循传统,制定一年的计划。不过,一年的时间很长,所以我以季节性的主题或轨迹来规划。每个季度,我都会坐下来,看看即将到来的三个月的季节,并决定在这段时间里我将努力做什么。
对于我最新的主题,我决定要每天写一篇日记。我喜欢有明确的承诺,所以我承诺每天写 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 timeoutcounter(reactor):
label = ipywidgets.Label(“Time left: 5:00”)
currentseconds = datetime.timedelta(minutes=5).totalseconds()
def decrement(count):
nonlocal currentseconds
currentseconds -= count
timeleft = datetime.timedelta(seconds=max(currentseconds, 0))
minutes, left = divmod(timeleft, minute)
seconds = int(left.totalseconds())
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(continuousupdate=False)
textarea.rows = 20
output = ipywidgets.Output()
runner = functools.partial(subprocess.run, captureoutput=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 = timeoutcounter(reactor)
textarea, output, save = editor(filename)
box = ipywidgets.VBox([
ipywidgets.Label(title),
textarea,
clock,
output
])
d.addCallback(save)
return box
“`
biu!你已经定义了一个写日记的函数了,所以是时候试试了。
“`
journal()
“`
你现在可以写 5 分钟了!
via: https://opensource.com/article/20/11/daily-journal-jupyter
作者:Moshe Zadka 选题:lujun9972 译者:wxy 校对:wxy
主题测试文章,只做测试使用。发布者:eason,转转请注明出处:https://aicodev.cn/2020/12/05/%e6%af%8f%e5%a4%a9%e7%94%a8-jupyter-%e5%86%99-5-%e5%88%86%e9%92%9f%e7%9a%84%e6%97%a5%e8%ae%b0/