每天用 Jupyter 写 5 分钟的日记

开发 后端
用 Jupyter 和 Python 在你的日常写作背后实现一些自动化。

[[355823]]

用 Jupyter 和 Python 在你的日常写作背后实现一些自动化。

有些人会遵循传统,制定一年的计划。不过,一年的时间很长,所以我以季节性的主题或轨迹来规划。每个季度,我都会坐下来,看看即将到来的三个月的季节,并决定在这段时间里我将努力做什么。

对于我最新的主题,我决定要每天写一篇日记。我喜欢有明确的承诺,所以我承诺每天写 5 分钟。我也喜欢有可观察的承诺,哪怕只是对我而言,所以我把我的记录放在 Git 里。

我决定在写日记的过程中实现一些自动化,于是我使用了我最喜欢的自动化工具:Jupyter。Jupyter 有一个有趣的功能 ipywidgets,这是一套用于 Jupyter Notebooks、JupyterLab 和 IPython 内核的交互式 HTML 组件。

如果你想跟着本文的代码走,请注意,让你的 JupyterLab 实例支持组件可能有点复杂,请按照这些说明来进行设置。

导入 ipywidgets 模块

首先,你需要导入一堆东西,比如 ipywidgets 和 Twisted。Twisted 模块可以用来创建一个异步时间计数器:

  1. import twisted.internet.asyncioreactor
  2. twisted.internet.asyncioreactor.install()
  3. from twisted.internet import reactor, task
  4. import ipywidgets, datetime, subprocess, functools, os

设置定时条目

用 Twisted 实现时间计数器是利用了 task.LoopingCall。然而,结束循环调用的唯一方法是用一个异常。倒计时时钟总会停止,所以你需要一个自定义的异常来指示“一切正常;计数器结束”:

  1. class DoneError(Exception):
  2.     pass

现在你已经写好了异常,你可以写定时器了。第一步是创建一个 ipywidgets.Label 的文本标签组件。循环使用 divmod 计算出分和秒,然后设置标签的文本值:

  1. def time_out_counter(reactor):
  2. label = ipywidgets.Label("Time left: 5:00")
  3. current_seconds = datetime.timedelta(minutes=5).total_seconds()
  4. def decrement(count):
  5. nonlocal current_seconds
  6. current_seconds -= count
  7. time_left = datetime.timedelta(seconds=max(current_seconds, 0))
  8. minutes, left = divmod(time_left, minute)
  9. seconds = int(left.total_seconds())
  10. label.value = f"Time left: {minutes}:{seconds:02}"
  11. if current_seconds < 0:
  12. raise DoneError("finished")
  13. minute = datetime.timedelta(minutes=1)
  14. call = task.LoopingCall.withCount(decrement)
  15. call.reactor = reactor
  16. d = call.start(1)
  17. d.addErrback(lambda f: f.trap(DoneError))
  18. return d, label

从 Jupyter 组件中保存文本

下一步是写一些东西,将你输入的文字保存到一个文件中,并提交到 Git。另外,由于你要写 5 分钟的日记,你需要一个能给你提供写字区域的组件(滚动肯定是可以的,但一次能看到更多的文字就更好了)。

这就用到了组件 Textarea,这是一个你可以书写的文本字段,而 Output 则是用来给出反馈的。这一点很重要,因为 git push 可能会花点时间或失败,这取决于网络。如果备份失败,用反馈提醒用户很重要:

  1. def editor(fname):
  2.     textarea = ipywidgets.Textarea(continuous_update=False)
  3.     textarea.rows = 20
  4.     output = ipywidgets.Output()
  5.     runner = functools.partial(subprocess.run, capture_output=True, text=True, check=True)
  6.     def save(_ignored):
  7.         with output:
  8.             with open(fname, "w") as fpout:
  9.                 fpout.write(textarea.value)
  10.             print("Sending...", end='')
  11.             try:
  12.                 runner(["git", "add", fname])
  13.                 runner(["git", "commit", "-m", f"updated {fname}"])
  14.                 runner(["git", "push"])
  15.             except subprocess.CalledProcessError as exc:
  16.                 print("Could not send")
  17.                 print(exc.stdout)
  18.                 print(exc.stderr)
  19.             else:
  20.                  print("Done")
  21.     textarea.observe(save, names="value")
  22.     return textarea, output, save

continuous_update=False 是为了避免每个字符都保存一遍并发送至 Git。相反,只要脱离输入焦点,它就会保存。这个函数也返回 save 函数,所以可以明确地调用它。

创建一个布局

最后,你可以使用 ipywidgets.VBox 把这些东西放在一起。这是一个包含一些组件并垂直显示的东西。还有一些其他的方法来排列组件,但这足够简单:

  1. def journal():
  2.     date = str(datetime.date.today())
  3.     title = f"Log: Startdate {date}"
  4.     filename = os.path.join(f"{date}.txt")
  5.     d, clock = time_out_counter(reactor)
  6.     textarea, output, save = editor(filename)
  7.     box = ipywidgets.VBox([
  8.         ipywidgets.Label(title),
  9.         textarea,
  10.         clock,
  11.         output
  12.     ])
  13.     d.addCallback(save)
  14.     return box

biu!你已经定义了一个写日记的函数了,所以是时候试试了。

  1. journal()

 

Jupyter journal

你现在可以写 5 分钟了! 

 

责任编辑:庞桂玉 来源: Linux中国
相关推荐

2020-09-24 05:50:46

PythonJupyter Not编程语言

2021-03-26 12:07:14

JupyterPython编程语言

2019-07-28 20:38:33

2015-07-17 10:02:48

写代码

2014-04-22 11:01:56

jQuery代码

2017-07-04 16:23:10

容器ocker技术

2020-11-13 06:18:07

JupyterPython数据分析

2020-07-25 19:40:33

Java开发代码

2021-01-29 14:50:20

APP手机热点推荐

2021-07-14 13:11:02

papermillJupyterPython

2012-01-04 09:50:07

程序员

2020-12-17 06:22:57

交互模式代码

2018-11-01 11:35:09

物联网IOT关键词

2021-06-02 14:53:33

程序员技能开发者

2022-01-06 18:20:20

Scarlet AndroidWebSocket

2018-02-26 09:28:42

程序员Bug体验

2021-08-12 16:02:22

Jupyter NotPython命令

2021-02-20 16:03:50

代码开发编程

2017-07-25 08:54:26

前端JsxVue

2023-11-29 08:10:36

javascriptH5游戏
点赞
收藏

51CTO技术栈公众号