最近在边看视频边做笔记,单个屏幕两个软件,因为经常需要暂停,快进,快退。软件焦点总会在浏览器和笔记软件切换。总是使用触摸板,误操作有点多。就写了个小插件,使用全局快捷键控制视频的播放,不需要在浏览器上操作,这样光标始终在笔记本上就好了

原理也很简单,使用油猴脚本连接本地websocket程序,监听到消息就对视频进行操作。本地程序监听全局快捷键就可以了。另外robotgo这玩意儿感觉不太好用….. 但是也没发现更好用的

阅读全文

在使用Anki制作卡片的时候为了醒目起见,需要修改文字颜色,最好是多种颜色交替,所以找了个插件Quick Colour Changing. 按照文档修改了配置,快捷键设置为了Ctrl+1/2/3/4. 结果发现完全没有反应。

看了下代码,只有十来行是很好理解的。代码逻辑正常,但就是没办法使用。想来一定是快捷键映射的问题。因为Anki基于PyQt构建,最后翻了下PyQt的文档. 有以下这句高亮标识

On macOS, references to “Ctrl”, CTRL , Key_Control and ControlModifier correspond to the Command keys on the Macintosh keyboard, and references to “Meta”, META , Key_Meta and MetaModifier correspond to the Control keys. Developers on macOS can use the same shortcut descriptions across all platforms, and their applications will automatically work as expected on macOS.

还是挺奇葩的,你写Ctrl会映射到Command, 写Command无效,写Meta映射到Command…..

所以在Mac上使用这个插件配置的时候需要特别小心…… 毕竟看起来非常违反直觉

参考

https://doc.qt.io/qtforpython-5/PySide2/QtGui/QKeySequence.html#more

PyQt QShortcut

Quick Colour Changing

PyQt print event

评论和共享

Kotlin DSL

发布在 kotlin

最近在看Kotlin,看到DSL部分觉得比较有意思,记录一下自己的理解

最简单的DSL就是各种大括号嵌套,每一个括号提供了一个独立的上下文,在该括号内使用这个上下文提供的api来影响上下文或者产生一些副作用。

Kotlin 天生就对DSL写法有比较好的支持,典型的scoping function: run、with、let、also、apply 就让大括号嵌套在Kotlin中无所不在

编写本文是因为看到了一段几十行的实现DSL的代码,觉得实现很简单,用法很炫酷,值得记录。代码链接在此 https://github.com/nazmulidris/color-console/blob/4d4503e183ab18434a9c86afd5ebdc66744c3451/src/main/kotlin/color_console_log/ColorConsoleLogUtils.kt#L91-L125

阅读全文

本文参照此处实现: 递归函数转非递归(通用方法)[1/2]——数据结构 递归函数转非递归(通用方法)[2/2]

先说总结,这种方案总的来说就是机械化的强转,时间复杂度和空间复杂度没什么变化,唯二的优点可能是1. 不会爆栈,2. 节省了函数调用的开销

而且最终产出的代码效果不那么美观,比较冗长

思路是:当发生递归调用时,模拟函数调用的压栈。并处理入参返回值记录返回到当前栈的时候该继续从哪里执行

阅读全文

原文: Tricks of the trade: Recursion to Iteration, Part 4: The Trampoline

这是关于将递归算法转换为迭代算法系列文章中的第四篇。如果你没有阅读过前面的文章,你可能想在继续之前阅读。

在我们系列的第一篇文章中,我们展示了如果你能将一个算法的递归调用转换为尾部调用,你就可以消除这些尾部调用,使用简单方法创建一个算法的迭代版本。在这篇文章中,我们将看看另外一种消除尾部调用的方法:trampoline

trampoline背后的思想是:在进行尾部调用之前,手动将当前执行的帧从栈中移除,消除栈堆积

阅读全文

原文: Tricks of the trade: Recursion to Iteration, Part 3: Recursive Data Structures

这是将递归算法转换为迭代算法系列的第三篇。如果下面的任何内容看起来令人困惑,你可能想先阅读前面两章的内容

这是我没有计划的一篇附加文章。之所以写它,是因为在上一篇文章的评论中,有读者要求我展示一个不那么数学化的例子,并建议使用树遍历。所以这就是这篇文章的主题。我们把一颗二叉树扁平化成一个列表,先是递归,然后是迭代

阅读全文

原文: Tricks of the trade: Recursion to Iteration, Part 2: Eliminating Recursion with the Time-Traveling Secret Feature Trick

这是将递归转化成迭代系列的第二篇。如果你还没有读过上一篇,你应该读一下。它介绍了一些有帮助的术语和背景知识。

上次,如果你还记得的话。我们讨论了将递归函数转化为迭代函数的简单方法。顾名思义,这种方法很简单,而且很机械。唯一潜在的问题是,要使用这种方法,你必须将函数中所有的递归调用转化为尾递归。

这个任务可能很棘手。因此,我们还讨论了将递归调用转化为尾递归的秘密函数技巧。这个技巧适用于简单的递归调用,但当调用不那么简单的时候,就需要一个更强大的版本。

这就是这篇文章的主题:时空旅行的秘密。这就像将T-800送到过去(来自电影终结者),终止一个函数的递归性

是的

但是我们得慢慢来。所以,坚持使用早起的例子,为后面困难例子做好准备。

说够了!让我们从一个实际的例子开始。

如果你想要另外一个例子,这里还有一个斐波那契数列的逐步转化

阅读全文

原文链接: https://blog.moertel.com/posts/2013-05-11-recursive-to-iterative.html

另一个标题:我希望python有尾递归消除

递归编程很强大,因为它很容易映射到通过归纳法来证明,这使得设计算法和证明算法的正确性变得容易。

但是很多流行的编程语言对递归的支持很差。在python中将一个大的输入丢进递归算法中,你可能会碰到运行时的递归限制。提高限制,你可能会耗尽栈空间从而触发段错误。

这些都很操蛋。

因此,一个重要的技巧就是知道如何将递归算法转换成迭代算法。这样以来,你就可以设计、证明和编写初步递归代码。在完成之后,你可以通过一系列机械化的步骤把你的算法转换成等价的迭代形式。

把递归变成迭代,这个话题足够吸引人,所以我打算做成一个系列的文章。尾部调用,trampolines(蹦床, 就是两个函数互相调用,可以参照[译] 使用JavaScript中的蹦床函数实现安全递归),continuation-passing style(参照CPS) 等等

本篇文章中,我们只看一个简单的方法和一个辅助的技巧。

阅读全文

分析stackoverflow热门问答

发布在 C

stackoverflow无疑是每个程序员的圣地,里面的问和答不知道解救了多少Copy-Paste党。更难能可贵的是它开放了自己的主要数据库,允许任何人对它的数据进行下载分析。让你用自己的方式去理解数据,实在是太激动人心了。其实类似的还有Github. 本文抛砖引玉。记录了我用它来发现哪些问题和解答是非常有价值的,然后自己可以针对性的查看学习

阅读全文

利用python去除PDF水印

发布在 python

最近手上有一份PDF资料,水印太多。非常影响阅读。所以写了一个脚本去掉水印。在两年前我折腾过给PDF增加隐藏的文本,说实话,个人感觉PDF格式还是很复杂的。好在很多PDF常见需求都有无数前人躺过坑。在网上搜了一下找了一个比较靠谱的改了一下

阅读全文

ficapy

author.bio


author.job


深圳