小学生口算题PDF打印版下载----神兽御免

2020年,家内神兽可以说已经完全放飞自我了……

数学基础一塌糊涂。

作为老爸,自然需要狠狠操练。

一个程序走起,PDF 可打印口算题出现了……(所以说,有个能写代码的老爸是神兽的不幸……)

  • 精美排版,符号对齐—-没有理由不做吧?
  • 每页100,数量恒定—-没有理由不做吧?
  • 黑体显示,拍照识别—-没有理由不做吧?

………………

下载:

继续阅读···

Python统计List的元素个数

以下两端代码,都可以实现。

Counter虽然强,但是数据量大的时候会比较慢。

自己写的轮子:

1
2
3
4
>>> test = [1, 2, 3, 4, 2, 2, 3, 1, 4, 4, 4]
>>> d = {k:test.count(k) for k in set(test)}
>>> d
{1: 2, 2: 3, 3: 2, 4: 4}

collectionsCounter 方法:

1
2
3
>>> from collections import Counter
>>> Counter(test)
Counter({4: 4, 2: 3, 1: 2, 3: 2})

水一贴测试下 Vercel 的自动脚本。

目前本站已经改为 Vercel 托管。coding 卖给腾讯后,页面托管那叫一个蛋痛……

Share下自己编译的 SumatraPDF 绿色汉化优化版

SumatraPDF, 开源,免费,多功能,小巧的PDF阅读器(当然,也支持很多流行书籍格式,诸如epub/Mobi/CHM)等等。

已经用了多年了。非常好用,不到6M的体积启动速度完爆各类浏览器。

不过,这个工具的绿色模式(aka,Portable)有个缺点,配置文件和缓存都会放到执行程序目录下。可是,哥习惯把一堆小型程序扔到一个OneDrive目录里面(是的,我就是 ~/bin 党)。

没办法,自己 Clone 下库,然后哼哧哼哧下载VS2019社区版。动手改造下。

(看代码+修改10分钟,搞定编译错误和链接问题20分钟,Clone代码半小时,下载VS2019两个小时……)

改造并不麻烦,见下:

继续阅读···

Python的Bool操作符--奇怪的逻辑但很有用

经常看到下面代码:

1
user_name = form['username'] or 'unknown'

一般来说,or操作符应该返回 bool类型。也就是说,上文代码的user_name 应该是 True 或者 False

php/perl用这种代码多的是,我能理解:

1
foo(bar) or die;

问题是,php/perl不能这么赋值啊……

python的这个逻辑还真挺诡异的……(是的,这种感慨一般来自c/c++程序员,我们较真)。

今日,又看到了类似代码。nnd,查查看。

于是,我得到了这个:

(Note that neither “and” nor “or” restrict the value and type they
return to “False” and “True”, but rather return the last evaluated
argument. This is sometimes useful, e.g., if “s” is a string that
should be replaced by a default value if it is empty, the expression
“s or ‘foo’” yields the desired value. Because “not” has to invent a
value anyway, it does not bother to return a value of the same type as
its argument, so e.g., “not ‘foo’” yields “False”, not “‘’”.)

确实灵活了,也符合人的第一感觉。但是……nnd,一个判断把类型换了到底是什么鬼啊……

不过,话说回来,用的时候……真香……虽然是今日查的,但是我已经用了N久了

就这样,水这么一贴是因为刚刚从半死不活的coding中换了blog服务器。测试下。

V2ray配置前置代理/代理链/链式代理转发

最近需要配置长连接跳板主机。大概的topology是这样的:

主要原因就是防火墙右侧主机设置了白名单,而左侧的服务器创建加密信道穿过防火墙,符合右侧服务器的白名单机制。

VPN配置很麻烦,而且很多国内地区禁用了VPN服务。

所以,用V2ray会简单很多。

V2ray的原理如下:

大概就是,用户主机通过SSR类型的前置代理链接左侧服务器,然后左侧服务器将流量通过VMess协议转发给防火墙右侧服务器。

配置如下:

继续阅读···

Process Substitution---Bash进程替换使用教程

故事起源一次不太愉快的运维面试:

1
2
3
4
5
6
7
8
Me: 一个巨型日志文件,如何一次性统计总行数,包含关键字error和warning的行数?
He: cat log | wc -l; cat log | grep error | wc-l; cat log | grep warning | wc -l
Me: .... , 这不算一次性啊,提示下,tee
He: .... , tee 只支持文件啊...
Me: cat log | tee >(wc -l) >(grep error| wc -l | awk '{printf "error is %s\n",$1}' ) >(grep warning | wc -l awk '{printf "warning is %s\n",$1}') | tee
He: cat log | tee >(...) >(...) 是什么诡异语法?
Me: 传说中的Process substitution啊,blablabla
He: ....

He同学吐槽了我司的奇葩需求后,拂袖而去。当然,主因是我司无法担负期望薪资…

那么,大才He同学不是很明白的诡异语法到底是啥?这里开贴解释一二。

吐槽一下,虽然各路大才都对 *nix下的万物皆文件的理念表示激赏。但真摸清楚文件/文件描述/管道/等基本概念的,还真没几个……

Process Substitution的详细解释,参看 wikimedia 。实际上,认真看完并深入理解后,就可以直接关闭本页。

当然,对这个都没啥很正规中文翻译的feature希望有个快速理解和人话白话理解的话,请继续阅读。

继续阅读···

Win10 Shell的快捷访问方式--Shell:

Windows 10 里面,在地址栏, 运行 等shell输入口里面,可以执行一些shell(explore)的快速内置指令。

一般利用:

1
shell:`command`

从网上查到了这个的全指令。这对键盘党还是很有用的。

顺便说一下,shell:::{2559a1f3-21d7-11d4-bdaf-00c04f60b9f0} 指令就是 打开运行窗口。这个蛮有趣的。

全指令如下:

继续阅读···

Python的多条件排序 -- 基于Tuple大小比较的语法糖

看到了个比较有趣的帖子,是关于Python列表排序的,参看:知乎的这个帖子

例子不难:

1
2
3
4
5
# 列表排序:先按照正负排序,再按照其绝对值排序
a = [1, -2, 10, -12, -4, -5, 9, 2]
a.sort(key=lambda x: (x < 0, abs(x)))
[1, 2, 9, 10, -2, -4, -5, -12]

其中,诡异的就是作为key的lambda函数了。

1
key=lambda x: (x < 0, abs(x))

一个返回tuple的函数,作为key,就可以实现多级排序。什么鬼?!

仔细查了下文档,发现原理是tuple的大小比较……

继续阅读···

Autossh for systemd --- ssh隧道自动加载

autossh 其实是一个ssh的扩展工具。一般应用在ssh 隧道建立/维护中。兼容全部ssh标准指令。可以自动重连服务。

不过,autossh不自带systemd的脚本。这里是修改的一套。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[Unit]
Description=Keeps an ssh tunnel
After=network-online.target ssh.service
[Service]
User=xxx
RestartSec=3
Restart=always
ExecStart=/usr/bin/autossh -v -nNT -R x.x.x.x:29528:localhost:29527 x.x.x.x
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target

复制到:

1
/etc/systemd/system/autossh.service

使用systemctl控制

1
2
3
sudo systemctl daemon-reload
sudo systemctl start autossh
sudo systemctl status autossh

参考的脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[Unit]
Description=Keeps an ssh tunnel to %I open
After=network-online.target ssh.service
[Service]
User=tunnel
# no monitoring
Environment="AUTOSSH_PORT=0"
# Disable gatetime behaviour
Environment="AUTOSSH_GATETIME=0"
EnvironmentFile=/etc/default/autossh@%i
RestartSec=3
Restart=always
# -NT Just open the connection and do nothing (not interactive, no tty alloc)
# use /usr/bin/ssh instead of autossh is good as well
ExecStart=/usr/bin/autossh -NT -o "ExitOnForwardFailure=yes" $SSH_OPTIONS ${TARGET_HOST} $FORWARDS
TimeoutStopSec=10
[Install]
WantedBy=multi-user.target

RunDll32.exe的黑科技

Rundll32是开发动态链接库的时候做单元测试的工具。其实就是个dll-loader。

Windows是DLL治国的,所有,很多系统功能都能简单的通过Rundll32直接在命令行里面call出来。

以下一些是一些有趣or有用的功能。

切换鼠标左右键(恶作剧专用)

1
Rundll32 User32.dll,SwapMouseButton

打开系统中已经保存的用户名和密码(挺方便的功能

1
RunDll32.exe keymgr.dll,KRShowKeyMgr

添加删除程序窗口

1
RunDll32.exe shell32.dll,Control_RunDLL appwiz.cpl,,0

打开内容分级窗口(for IE)

1
RunDll32.exe msrating.dll,RatingSetupUI

打开控制面板

1
RunDll32.exe shell32.dll,Control_RunDLL

删除临时文件(for IE)

1
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 8

删除Cookie(for IE)

1
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 2

删除历史(for IE)

1
RunDll32.exe InetCpl.cpl,ClearMyTracksByProcess 1

继续阅读···

vol.moe 的批量选取油猴脚本

最近学习了点javascript。这东西挺好玩的。

正好日常网站vol.moe的一些功能很不顺手。就改写下。

  • 没全选推送。(当你要试着推送一整套海贼王的时候,你真的挺恨网站作者的)
  • 每次都是同一标签打开漫画详情。(一不小心关了,之前的翻页就算废了)

于是,做了个油猴脚本。

安装地址见此:Greasyfork

源代码:Github

Bug反馈:Github Issue

代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
// ==UserScript==
// @name vol.moe 增强工具
// @namespace monkeypatch.moe.vol
// @version 0.1
// @description * 新窗口打开漫画页详情。 * 漫画页中,添加全选按钮,批量选择推送的漫画。
// @author Shazoo
// @match http*://vol.moe/comic/*.htm
// @match http*://vol.moe/
// @match http*://vol.moe/list/*
// @grant none
// ==/UserScript==
(function() {
'use strict';
// Your code here...
var cur_url = window.location.href;
if (/^https?:\/\/vol\.moe\/comic\/\d+\.htm/.test(cur_url)){
// 给漫画详情页添加全选功能
var loc_btn = document.getElementById('push_button');
var ctrl_btn = document.createElement('template');
ctrl_btn.innerHTML='<a href="javascript:void(0);" id="ctrl_btn" style="margin-right: 10px;" class="weui_btn weui_btn_mini weui_btn_default">全选</a>';
ctrl_btn = ctrl_btn.content.firstChild;
loc_btn.parentNode.insertBefore(ctrl_btn, loc_btn);
var is_selected = false;
ctrl_btn.addEventListener('click',function(){
is_selected = ~is_selected;
var cb = document.getElementsByName('checkbox_push');
for (var idx=0; idx < cb.length; idx++) {
cb[idx].checked = is_selected;
}
sum_push_item();
}, false);
}else {
// 在列表页面添加新窗口打开功能
var alist = document.getElementsByTagName('a');
for (var idx = 0; idx < alist.length; idx++) {
if (/comic\/\d+\.htm/.test(alist[idx].href)){
alist[idx].target = '_blank';
}
}
}
})();