普通视图

发现新文章,点击刷新页面。
昨天以前炎忍的博客

诡辩术

作者 炎忍
2020年11月30日 13:46

“晓之以理”

诉诸匿名权威

诉诸匿名权威

引用来源不详的“ 砖家”、“研究”或某一群体(比如“科学家”)以声称某观点是正确的。
“他们说要花7年才能消化一片口香糖。”

诉诸(可疑)权威

诉诸(可疑)权威

因为某个无实无信的“专家”说某件事是真的,因而断言确实如此。
“超过400位杰出的科学家与工程师对全球变暖持争议态度。”

诉诸常规

诉诸常规

因为常见,所以正确。
“这家银行有些贪污腐败方面的问题。但在这里发生的事不是在哪家银行都在发生嘛。”

诉诸无知

诉诸无知

某一观点是正确的,仅仅因为它没有被证伪(或某观点是错误的,仅仅因为它尚未被证实)
“没人能证明有上帝。所以没有上帝。”

诉诸怀疑

诉诸怀疑

因为某件事听起来不可信,所以一定不是真的。
“眼睛是超级复杂的生物机械之作,有千万个紧密联系的部件。如果没有一位睿智的设计师,这怎么可能存在?”

身价逻辑

身价逻辑

如果某人很有钱,或者某样东西很贵,那么这就对某一论断的真实性造成了影响。
“如果这玩意儿更贵的话,那它一定更好。”

求新逻辑

求新逻辑

因为是最新的,所以更好。
“太棒了!最新的操作系统会让我的电脑跑得更快的…”

诉诸主流

诉诸主流

认定某件事是真的,因为大多数人都这么相信。
“喝牛奶能使你骨骼强健。”

诉诸概率

诉诸概率

相信因为某件事情可能发生,所以必然会发生。
“宇宙里有数不清的星系,无数多的星星。一定有另一颗行星孕育了智慧生命。”

诉诸传统

诉诸传统

声称某件事是正确的,因为(很显然)一直以来都是这样。
“婚姻是男与女的结合。因此同性婚姻毫无根据。”

“动之以情”

掩耳盗铃

掩耳盗铃

声称某个观点是错误的,因为你不愿意相信那所意味的事实。
“他不可能就是为了骗我的钱。他说过他爱我的,他一定是遭到了什么变故。”

诉诸恐惧

诉诸恐惧

煽动对一方的恐惧与偏见,从而进行论证。
“在你意识到之前,清真寺的数目就会超过教堂了。”

诉诸谄媚

诉诸谄媚

给毫无根据的论点裹上糖衣炮弹,让人不自觉地全盘接受。
“聪明又有洞察力的读者当然在读到这样的谬误时就能马上发觉。”

诉诸自然

诉诸自然

通过与“至善”的自然界的对比,来使你的观点看起来更站得住脚。
“同性恋当然违背天性。你看不到同性动物交配吧。”

诉诸同情

诉诸同情

唤起人们的怜悯之心,以动摇对手。
“前独裁者已垂垂老矣,濒临末年。让他为这些指控接受审判实在不应该。”

诉诸荒谬

诉诸荒谬

将对手的观点以荒谬的形式表现出来以进行打击。
“对上帝的忠诚就如同相信有圣诞老人和牙仙一样。”

诉诸仇恨

诉诸仇恨

因为个人偏见而对某一看法不屑一顾。
“富二代搞慈善?算了吧,反正还不是在做秀。”

一厢情愿

一厢情愿

认为一件事是真的或假的,仅仅因为你情愿想当然。
“主席是不会犯错的。他是人民的领袖,红旗的舵手。”

错误推论

轶事证据

轶事证据

对系统性研究下得出的证据视而不见,反而集中在手头的个例上。
“我才不戒烟呢。我爷爷每天抽40根,还活到了90岁!”

合成谬误

合成谬误

推断一群人的特性或信条也代表了整个团体。
“最近的恐怖袭击是由激进的伊斯兰教徒组织的。因此所有的恐怖分子都是穆斯林。”

分割谬误

分割谬误

将整个团体的特性或信条自动代入到每一名成员的头上。
“苹果的产品向来颠覆传统,设计一流。下一款也一定如此。”

设计谬误

设计谬误

因为某样东西设计精美,视效上佳,所以更加站得住脚。
“呃…”

赌徒谬误

赌徒谬误

认为历史结果会影响未来结果。
“我已连续丢了10次硬币,都是正面朝上。因此下一次更可能丢出反面来。”

轻率概化

轻率概化

从单一的样本得出概括性的结论。
“我被前面的女驾驶别了下。女人就是不能开车。”

妄下定论

妄下定论

没有公平考虑所有相关(且易举证的)事实,就妄下结论。
“她想要医疗保险报销避孕药?真是个婊子。”

中间立场

中间立场

相冲突的两个观点似乎都有道理,那么答案一定在两者的中间地带。
“我追尾了你的车,但我不认为自己该出修理费。你认为我该出所有的修理费。合乎情理的方案就是平分费用。”

完美主义谬误

完美主义谬误

认为只有完美的成功才是可行的选择,从而反对任何低于预期的方案。
“这反酒驾的宣传究竟有什么用?人们还是会醉酒驾车的。”

相对论谬误

相对论谬误

否定某样客观事实,认为事实是相对一个或一群人而言的。
“那对你来说可能是对的。但对我来说不是。”

以偏概全

以偏概全

认为从小样本观察到的同样适用于整体。
“这家大型制鞋商在血汗工厂里雇用童工。可想而知所有制鞋公司都是邪恶的童工奴隶主!”

一概而论

一概而论

宽泛地应用一般性原则。
“那些年轻人暴乱是因为他们缺失有道德观念的父亲。”

中词不周延

中词不周延

因两件事有一个共通点,那么他们就是同一回事。
“理论是尚未证实的观点。科学家用‘进化论’这一词,可见进化是未被证实的。”

操纵内容

临阵救援

临阵救援

通过不断修改论据,搪塞问题,来保全自己的一贯主张。
“…但除了更好的卫生,医药,教育,灌溉,公共卫生,道路,净水系统和公共秩序…罗马人为我们做了什么?”

一孔之见

一孔之见

用不具代表性的样本所得出的结论,来支持自己的论点。
“我们的网上调查表示,90%的互联网用户反对网络隐私法。”

确认偏误

确认偏误

挑拣对自己有利的证据,而故意无视相冲突的。
“很明显911事件是美国政府为了合理化伊拉克与阿富汗战争而发动的阴谋。没有飞机撞上五角大楼。双子塔的倒塌是控制爆破。。。等等”

伪二分法

伪二分法

隐藏其它可能性,将两个对立的观点看作仅有的选择。
“我们要么就得削减教育预算,要么就得负更多的债。我们不能负更多的债了,所以我们非降低教育预算不可。”

谎言

谎言

彻头彻尾的谎言,被作为真相一再重复。
“我没有和那个女人发生性关系。”

误导性鲜活个案

误导性鲜活个案

用生动的细节来描述一次小概率事件,以让别人相信这是一个问题。
“在法院判决同性婚姻合法化之后,学校图书馆被要求存有同性文学作品;小学生会读到同性恋的童话故事,甚至有明确支持同性恋的手册。”

转移注意

转移注意

将毫不相关的话题引入辩论,以干扰视线并导向不同的结论。
“参议员不需要为他开销的异常做出说明。毕竟,有些参议员做的破事儿比这严重多了。”

滑坡谬误

滑坡谬误

认为开始的一小步会无可避免地引发一串相关(负面)的事件。
“如果我们将大麻合法化,更多的人就会开始吸食毒品和海洛因。到时候我们就得也合法化那些。”

隐瞒证据

隐瞒证据

有意不用相关且重要的信息,因为那对立于自己的结论。
“炒菜产生的油烟是PM2.5的重要来源,所以要治理雾霾,中国人就得少做菜。”

无法证伪

无法证伪

提出一个无法被证伪的观点,因为无法加以验证。
“他撒谎是因为鬼上身了。”

混淆因果

肯定后件

肯定后件

认为对你所观察到的现象只有一种解释。
“婚姻会带来孩子的降生。所以这就是其存在的理由。”

循环逻辑

循环逻辑

论证的前提里已经蕴含结论。
“《圣经》上说上帝存在。由于圣经是上帝的话,圣经必然正确。所以上帝是存在的。”

相关即因果

相关即因果

认为两个一起发生的事件一定有因果关系。(关联性=因果性)
“小混混们听主题暴力的饶舌音乐。所以饶舌音乐会造成青少年的暴力行为。”

否定前件

否定前件

有这样的结果并非只有一个解释。因此,在这样的情况下从结果反推原因是不准确的。
“如果你读了好学校,你就会找到好工作。如果你没读好学校,你就找不到好工作。”

忽视主因

忽视主因

声称是某事件导致了后果,而实际上另一件(意料之外)的事才是原因。
“60年代我们开始了性解放运动,而现在人们正死于艾滋。”

前后即因果

前后即因果

因为一件事是在另一件事之后发生的,因此也是由那件事引起的。“总统上台之后,失业人数创了历史新高。所以总统阻碍了经济发展。”

积非成是

积非成是

认为一桩错事能被另一桩错事所抵消。
“不错——这监狱环境恶劣又没人性,不过关的本来就是罪犯!”

发起进攻

人身攻击

人身攻击

绕开论证,针对辩论者本身发起不相干的攻击。
“你以为自己是生物学专家吗,也好意思来教我们转基因食品的事?”

举证责任

举证责任

我不需要证明我说的正确——你必须证明它是错的。
“我坚持认为长期的太阳活动周期是全球变暖的原因。证明我错了啊。”

身份主观

身份主观

认为一个论断不可信,因为支持者与之有利益关系。
“研究手机对健康影响的这个调研有手机公司参与。所以,研究结果不可信。”

基因谬误

基因谬误

攻击一个论点的来源,而非它的内容。
“这本书是1967年出版的,里面说的东西哪还有价值。”

罪恶关联

罪恶关联

通过将一个论点与形象不良的人或群体联系起来,从而破坏其可信度。
“哦,你想要放松反恐条例,就像那帮恐怖分子想要的一样。所以你是支持恐怖主义的啰?”

稻草人谬误

稻草人谬误

歪曲或简化你对手的论点,以攻击之。甲:“国家应该投入更多的预算来发展教育行业。” 乙:“你这么不爱国,居然想减少国防开支,让外国列强有机可乘。”

参考内容

解决方案.方案

作者 炎忍
2020年11月14日 14:07

日常解决问题基本靠 Google,拿来水博客跟 Copy&Paste 也没啥区别,但是又想把这些方法记录下来,万一以后需要用还方便查看,于是打算全部写在这一篇文章里了。

当然,为了防止未来的我忘记当时写的是什么东西,咱尽量将一些因人而异、因机而异的东西标注出来(比如每段的 Replacement),但难免有疏漏,如果有读者能够看到,并感到疑惑,请不要吝啬你的留言。[1]

因为我是用的是 Windows 10 系统所以一下的东西只保证在 Windows 10 有用其他系统,诸如 Windows 7/Linux/macOS 请自行查找方案

目前可用的 VS Code 调试 C/C++ 配置

2020-11-12 19:53 GMT +8
基于网上现有的稍加修改

请替换 [debugger_path] 并且保证你的 gcc 是可用状态,或者使用其他的编译器/调试器

launch.json

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
{
// 使用 IntelliSense 了解相关属性。
// 悬停以查看现有属性的描述。
// 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
"version": "2,0.0", //配置文件的版本,以前使用是0.2.0,新版本已经弃用,改用为2.0.0
"configurations": [
//配置域
{
"name": "(gdb) Launch", //配置文件的名字,可以随便起
"type": "cppdbg", //调试的类型,Vscode现在支持很多,我这里主要是C,所以只能是cppdbg
"request": "launch", //配置文件的请求类型,有launch和attach两种,具体看官方文档
"targetArchitecture": "x64", //硬件内核架构,为64bit,如图设置
"program": "${workspaceRoot}/${fileBasenameNoExtension}.exe", //可执行文件的路径和文件名称
//"args": ["file1", "file2"], //主函数调用时传入的参数
"stopAtEntry": false, //设为true时程序将暂停在程序入口处
"cwd": "${workspaceFolder}", //调试时的工作目录
"environment": [], //不知道干嘛的
"internalConsoleOptions": "openOnSessionStart", //
"externalConsole": true, //调试时是否显示控制台窗口
"MIMode": "gdb", //指定连接的调试器,可以省略不写
"miDebuggerPath": "[debugger_path]/gdb.exe", //调试器路径,在Linux环境下需要注释掉这一行
"preLaunchTask": "gcc", //调试会话开始前执行的任务,一般为编译程序。与tasks.json的label相对应
"setupCommands": [
//不知道干嘛的
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
}
]
}
]
}

tasks.json

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
{
"version": "2.0.0",
"tasks": [
{
"label": "gcc", // 任务名称,与launch.json的preLaunchTask相对应
"command": "gcc", // 要使用的编译器
"args": [
"${file}",
"-o", // 指定输出文件名,不加该参数则默认输出a.exe,Linux下默认a.out
"${fileDirname}/${fileBasenameNoExtension}.exe",
"-g", // 生成和调试有关的信息
"-Wall", // 开启额外警告
"-fexec-charset=GBK" // 防止中文乱码,按需取用
], // 编译命令参数
"type": "cppbuild", // 可以为shell或process,前者相当于先打开shell再输入命令,后者是直接运行命令
"options": {
"cwd": "[debugger_path]/bin"
},
"problemMatcher": ["$gcc"],
"group": "build",
"detail": "compiler: gcc"
}
]
}

Win10 任务栏菜单小图标变黑了

2020-9-10 16:55 GMT+8
建议创建开机任务执行

1
ie4uinit -show

通过 JDK 生成 JRE

2020-9-22 9:36 GMT+8

需要管理员权限的 CMD 运行

1
2
cd %JAVA_HOME%
bin\jlink.exe --module-path jmods --add-modules java.desktop --output jre

使用 hexo-reference 插件生成脚注编号重复

  1. 找到 \<blog_root_folder>\node_modules\hexo-reference\src\footnotes.js

  2. 删除或者注释这几行代码

1
2
3
4
5
6
7
8
9
10
11
// render footnotes (HTML)
footnotes.forEach(function (footNote) {
html += '<li id="fn:' + footNote.index + '">';
->// html += '<span style="display: inline-block; vertical-align: top; padding-right: 10px; margin-left: -40px">';
->// html += footNote.index;
->// html += '.</span>';
html += '<span style="display: inline-block; vertical-align: top; margin-left: 10px;">';
html += md.renderInline(footNote.content.trim());
html += '<a href="#fnref:' + footNote.index + '" rev="footnote"> ↩</a></span></li>';
});

Grub 找不到 Windows 引导了

2021-3-19 11:12 GMT+8
我是用的是 Manjaro

首先需要安装 os-prober,然后打开 /etc/default/grub,编辑或者添加以下几项

1
2
3
GRUB_TIMEOUT_STYLE=menu  #显示菜单
GRUB_TIMEOUT=10 #超时时间10秒
GRUB_DISABLE_OS_PROBER=false #允许os探测

修改完成后运行 sudo update-grub 就可以找到 Windows 引导了。

修改 Windows 10 的用户名以及用户文件夹

作者 炎忍
2020年9月15日 22:54

修改注册表有风险,操作需谨慎,注意备份重要文件

由于 Windows 10 的奇葩机制本地账户名是在线账户邮箱的前五位,导致我登录在线账户之后在本地显示的名称以及文件夹从我名字全拼的 nihaocun 变成了 nihao,虽然能忍,但是越看越不顺眼,就开始在网上找修改的方法。然而搜到的结果也大多不完整,好在还是能拼起来的,现在终于是改成功了。

以下操作在 你的个人账户 完成

开启 Administrator 账户

我们需要开启这个账户去修改注册表和文件夹名,家庭版用户请先升级到专业版,专业版用户打开控制面板 -> 系统和安全 -> 管理工具 -> 计算机管理,然后按图所示依次打开本地用户和组 -> 用户 -> Administrator,然后去掉 账户已禁用 前面的复选框即可。开启 Administrator 账户

修改用户名

接着不关闭计算机管理,找到你需要修改的用户名,然后右键重命名即可,注意这里不能和计算机名重复(大小写不敏感)

以下操作在 Administrator 完成

修改注册表

注销当前账户切换到 Administrator,按下 Win + R 打开命令窗口,输入 regedit 回车运行打开注册表编辑器。使用 Ctrl + F 搜索 ProfileList 或者手动定位到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsNT\CurrentVersion\ProfileList 这一项。在这里有很多 S-1-5 开头的项,依次检查会有一个 ProfileListPathC:\User\<你的用户名> 这一项,双击修改即可。修改注册表

修改文件夹名

在文件管理器找到 C:\User\<你的用户名> 然后直接修改即可。

以下操作在 你的个人账户 完成

创建联接

现在回到原来的账户发现名字已经改了,而且原来的数据还在,不过部分环境变量以及应用配置可能会出问题,这里提供两个方法:

  • 一个一个修改路径保证不出错
  • 创建一个联接

    用管理员权限运行一个 CMD 窗口,然后输入 MKLINK /J C:\Users\<旧用户名> C:\Users\<新用户名>,这样不论访问 C:\Users\<旧用户名> 还是 C:\Users\<新用户名> 都会定位到 C:\Users\<新用户名>。出现下图这样就是成功了。创建联接

怎么呼吸

作者 炎忍
2020年7月3日 11:34

不能呼吸的时候是不是很难受?这只海龟也是这么觉得的image怎么救它?尽量不去用一次性的塑料产品比如 不买一次性塑料袋喝饮料的时候不要用吸管放一双公筷点外卖的时候选择「不要餐具」随身带一个保温杯不强求一步到位也不去强迫别人改变从自身的一点点到地球的「亿」点点

在 Windows 系统上给 ssh 设置代理

作者 炎忍
2020年6月1日 23:28

看清,使用的系统是 Windows 不是 Linux 或者 MacOS

百度搜到的很多给 git 设置代理的办法,都是给 http 设置代理,而不是给 SSH 设置代理。那个 git config --global http.proxy http://127.0.0.1:1080 设置起来,只针对 http 的 git 有效果。然后就是 ProxyCommand nc -v -x 127.0.0.1:1080 %h %p,那个分明是给 Linux 才能用的, Windows 上哪里来的 nc 程序?

以下操作是给 Windows 用的,我的操作:

在自己的用户文件夹找到 .ssh 文件夹,比如我的是 C:\Users\nihao\.ssh ,在里面新建一个空白文件,取名 config,如果已经有了就不用创建了。

注意不是 config.txt !

我强烈建议把 Windows 的后缀显示给打开,不然你根本不知道自己到底在编辑什么文件。

都用 Git 了不至于还害怕自己把文件后缀名给改错了吧?

在 config 文件里写上一行就行:

1
ProxyCommand "C:\Program Files\Git\mingw64\bin\connect.exe" -S 127.0.0.1:1080 %h %p

这里 git 的安装路径和后面的代理自己看着填,不要试着用相对路径,保证要吃亏。因为 Program Files 文件夹中间带一个空格,所以这里需要把整个路径给引号引起来。 后面的代理的话,-S 指是 socks 代理,默认是 socks5,127.0.0.1:1080 就是你本地的代理地址,后面的 %h %p 意思是 Host 和 Port,必须得写上,我也不知道为什么要这么设计。 如果要使用 HTTP 代理,就写 -H,更多代理类型(比如 socks4)请参 这个

上这个写法是针对全局的,如果想只针对某个网站的话,就这么写:

1
2
Host github.com
ProxyCommand "C:\Program Files\Git\mingw64\bin\connect.exe" -S 127.0.0.1:1080 %h %p

现在就可以愉快的使用代理了,不过要记住一定使用 ssh 协议。

开往 - Travellings

作者 炎忍
2020年4月22日 11:14

什么是开往

这是一个来自于国外的想法,在网站显眼的位置,加入一个认证的徽标,代表网站已经加入了友链助力,如果访客点击徽标,将随机前往另一个计划内的网站。

为什么要开往

互联网将人与人之间的距离大大减小,却还是形成了大大小小的孤岛。只有熟人间才知道彼此,而陌生人永远只能是陌生人。

“开往”取自“开放的网络”。 将一群志同道合的人连接在一起,我们共享彼此的流量,帮助陌生人发现新大陆。

开往-友链助力是传统友链的增强,我们不必互相知道了解彼此,标准的审查让友好的朋友加入我们,只需要一个徽标,占用一块位置,我们所有人都联系在了一起,简单而又强大。大大小小的孤岛散落在浩瀚烟海,开往就像是一颗颗星球之间的快速列车,随机的跳向下一站。

怎么加入开往

开往-友链接力

这是项目的 Github 地址,在 issue 中提交申请,几日内就会受理。但是申请的网站必须满足几点要求:

  1. 愿为开放的网络做出贡献(如分享知识经验设计等);
  2. 没有违法以及影响体验的内容(如侵入式广告等);
  3. 正常更新维护中(国内无法正常访问会被移除);
  4. 强制启用 https 。

满足以上要求,并将徽标插入您网页明显的地方(让友链传递下去)。

下面就是通向异域的按钮。

开往-友链接力

为什么说宣扬读书无用论的人要么蠢要么坏?

作者 炎忍
2020年3月3日 23:23

告诉别人「读书无用」的人,也许他们真的没读过什么书,因为一些机缘巧合,或者家庭资源帮扶,让他们得到了一些成就。

但你没办法像他们那么幸运。

读书面对强者,应该是锦上添花;对弱者,应当是雪中送炭。

读书不单是指文化课,我们需要的是一直保持持续学习的习惯。

如果你丧失了持续吸收新鲜事物的技能,那你的生活就会处在一个瓶颈。

这个时候,你就会发现你身边的傻逼上司,傻逼同事和傻逼的朋友,都会层出不穷。

但你跳不开这个境地,因为你真的相信了读书无用,换言之,你智商也不怎么地。

半自动化生成博客相册

作者 炎忍
2020年2月18日 13:10

下面有完整代码,自行复制

环境

  • Hexo Butterfly 主题

  • 本地运行脚本需要安装 Python 3

文件层级要求

首先你要知道 Butterfly 的相册格式,类似下面这样:

1
2
3
{% gallery %}
markdown 图片格式
{% endgallery %}

当然里面可以插入网络图片或者本地图片,如果你是网络图片或者混用就不用往下看了,这里只针对使用本地图片。

然后文件层级要类似下面这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|   // 这是 Hexo 博客的根目录
| // 其他文件我就省略了
|
└── source // Hexo 的资源文件目录
|
| // 省略其他文件夹
|
└── gallery //相册文件夹,名字可自定义
├── index.md // 相册的界面文件
├── images.py // 生成脚本
└── images // 放图片的文件夹
|
......
//很多图片

或者形如以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|   // 这是 Hexo 博客的根目录
| // 其他文件我就省略了
|
└── source // Hexo 的资源文件目录
|
| // 省略其他文件夹
|
└── gallery // 可能是一个集合文件夹或者其他
|
|
└── (1-n 级文件夹)// 多少层都无所谓
|
└── photo //真正的相册
├── index.md // 相册的界面文件
├── images.py // 生成脚本
└── images // 放图片的文件夹
|
......
//很多图片

然后我们打开 index.md 的大概结构如下:

1
2
3
4
5
---
title: 相册
type: "picture"
---
// 剩下的最好为空,不过问题不大

脚本

首先贴上完整脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import os

path = os.path.split(os.path.realpath(__file__))[0]

path2 = path[path.rfind("source")+6:]

os.chdir(path+"\images")
ls_file = []
for file in os.scandir():
if file.is_file():
ls_file.append(file.name)

md_text = "\n{% gallery %}\n"

for image in ls_file:
md_path = "!["+os.path.splitext(image)[0]+"]("+str(path2)+"\\"+image+")"
md_text += md_path.replace("\\", "/")+"\n"

md_text += "{% endgallery %}"

os.chdir(path)

with open('index.md', 'a', encoding='utf-8') as f:
f.write(md_text)
  • 仅适用于 Windows 系统,如果是 Linux 要做出微小修改。
  • 使用前需要清除之前生成的相册格式

将此脚本保存到和 index.md 同级目录,然后定位到该目录执行 python <你保存的文件名>.py 即可使用。

解析

下面我来解析一下这个脚本,轻喷,我两天前才玩的 Python

导入模块

首先使用 import os 导入 os 模块

获取路径

1
2
path = os.path.split(os.path.realpath(__file__))[0]
path2 = path[path.rfind("source")+6:]

获取脚本所在位置的绝对路径保存在 path,使用 rfind() 函数从右往左找到第一个 source 字符如果你后面也有自己起这个名字的文件夹我就没办法了,然后使用分片截取 source\ 后的路径保存在 path2

遍历文件名

1
2
3
4
5
os.chdir(path+"\images")
ls_file = []
for file in os.scandir():
if file.is_file():
ls_file.append(file.name)

使用 chdir() 切换工作目录到当前目录下的 images 目录,也就是放图片的目录,以便获取图片,然后遍历目录下的所有文件名称保存在 ls_file 中。

处理格式

1
2
3
4
5
6
7
8
md_text = "\n{% gallery %}\n"

for image in ls_file:
md_path = "!["+os.path.splitext(image)[0]+"]("+str(path2)+"\\"+image+")"
md_text += md_path.replace("\\", "/")+"\n"

md_text += "{% endgallery %}"

现在我们已经获取好了所有文件名,并且得到了 path2——从 source 到当前位置的相对路径

接着在第 1 行和第 7 行声明了相册的基本格式,第 3 行到第 5 行使用循环处理好了 MarkDown 图片格式。

1
![描述](链接/路径)

这是 MarkDown 图片格式,所以我们要把去掉后缀的文件名放到 描述 中,把图片的相对路径放到 链接/路径 中。

os.path.splitext(filename) 就可以轻松分开文件名和后缀,由于我们只需要文件名所以使用 os.path.splitext(image)[0],这里已经传入了文件名。

然后使用 str() 把相对路径 path2 转化为字符串并且加上图片的文件名。

最后整理好格式,使用 + 将各部分连接好,并且使用 replace() 替换所有的 \/ 就成型了。

写入文件

1
2
3
4
os.chdir(path)

with open('index.md', 'a', encoding='utf-8') as f:
f.write(md_text)

上一步已经把处理好的相册格式存放在 md_text 中,紧接着使用 chdir() 切换到脚本所在目录,这里有 index.md 以便我们写入。

with open(filename) as file: 这是固定格式,不必多讲,不过一定要注意使用 'a' 切换到追加模式,以免丢失原来的模板;使用 encoding='utf-8' 指定编码,以免写入中文时乱码。

懒是人类进步阶梯

这是我用 Python 写的第一个玩意儿,主要是每次都要手动加好麻烦,我就想能不能用 Python 写一个脚本处理。学了两天,写的不是很好,比如不能自动识别原来已有的格式进行替换,每次都要手动去清除,又或者得手动执行,不能在 Hexo 部署的时候进行执行。

Git 无法 Pull 仓库 显示 refusing to merge unrelated histories (拒绝合并不相关仓库)

作者 炎忍
2019年10月19日 22:54

如果在合并 pull 仓库的时候,出现的问题如何去解决(这个方法适用于合并本地很久没有提交的仓库,或者是同一个仓库 commit 信息不同的合并)

示意图

如果合并了两个不同的开始提交的仓库,在新的 git 会发现这两个仓库可能不是同一个,为了防止开发者上传错误,于是就给下面的提示

1
fatal: refusing to merge unrelated histories

如我在 GitHub 新建一个仓库,写了 License,然后把本地一个写了很久仓库上传。这时会发现 GitHub 的仓库和本地的没有一个共同的 commit 所以 git 不让提交,认为是写错了 origin ,如果开发者确定是这个 origin 就可以使用 --allow-unrelated-histories 告诉 git 自己确定

遇到无法提交的问题,一般先 Pull 也就是使用 git pull origin master 这里的 origin 就是仓库,而 master 就是需要上传的分支,因为两个仓库不同,发现 git 输出 refusing to merge unrelated histories 无法 pull 内容

因为他们是两个不同的项目,要把两个不同的项目合并,Git需要添加一句代码,在 git pull 之后,这句代码是在 Git 2.9.2 版本发生的,最新的版本需要添加 --allow-unrelated-histories 告诉 git 允许不相关历史合并

假如我们的源是 origin,分支是 master,那么我们需要这样写 git pull origin master --allow-unrelated-histories 如果有设置了默认上传分支就可以用下面代码

1
git pull --allow-unrelated-histories

Kirby Assistant 2.x.x更新日志

作者 炎忍
2019年9月10日 12:51

目前最新版本 v2.0.6 (56)

v2.0.6 (56)

紧急修复了高版本无法安装的问题,并且移除的权限,很是抱歉

v2.0.5 (55)

1.修改部分样式贴近规范2.修改下载游戏时的对话框样式

v2.0.4 (54)

1.修复个别主题下输入框颜色不正常的问题2.排除了一个引起闪退的 bug3.新增一个配色

v2.0.3 (53)

1.修复部分黑暗模式与白色模式下的UI问题2.修复UI漂移的问题

v2.0.2 (52)

1.修正夜间模式下设置显示异常2.修复闲聊显示异常问题3.修复无法清除图片缓存4.修复更新检测异常5.重新优化的主题

v2.0.1 (51)

1.自动根据 AndroidQ 夜间模式选项切换夜间模式2.翻译文本修正3.图片资源修复

v2.0.0 (50)

1.全新 API 重新编写2.大部分 MD2 特性3.修复底栏切换过快崩溃的 Bug4.新增黑暗模式5.假装无缝切换主题6.优化用户信息修改后刷新操作7.优化菜单显示方式8.防止未登录情况下进入闲聊的问题9.重新优化的对话框10.应用内清除缓存11.重写头像裁剪12.上传逻辑13.全新官网

动态替换 ViewPager 里面的 Fragment

作者 炎忍
2019年8月17日 13:40

最近在重写 Kirby Assistant 过程中又遇到了需要动态替换 ViewPager 的某个 Fragment 的需求,因为之前的是直接在同一个布局里暴力替换的,但是这次因为是用其他方法实现的,当然不能用以前的方法了,摸索了一段时间后终于搞定了,现在把可以用的方法放在下面

准备过程

首先需要在布局中添加 ViewPager

1
2
3
4
<androidx.viewpager.widget.ViewPager
android:id="@+id/main_fragment_viewpager"
android:layout_width="match_parent"
android:layout_height="match_parent"/>

然后给 ViewPager 写一个 ViewPagerAdapter 并且继承自 FragmentPagerAdapter

1
2
3
public class ViewPagerAdapter extends FragmentPagerAdapter {
//其他东西
}

重写 ViewPagerAdapter

具体看代码的注释,有注释的都是需要注意的

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
public class ViewPagerAdapter extends FragmentPagerAdapter {

private FragmentManager fm;
private List<Fragment> fragments;
private List<String> page_title;//这个是对应碎片的标题,可以不需要

public ViewPagerAdapter(FragmentManager fm, List<Fragment> fragments,List<String> page_title){
super(fm);
this.fm=fm;
this.fragments=fragments;
this.page_title=page_title;
}


//注意这个方法,这个是配置你在哪个碎片上进行替换
@NonNull
@Override
public Object instantiateItem(@NonNull ViewGroup container, int position) {
//这里的判断说明的是在三个和第四个碎片上替换
if (position == 2||position == 3)
removeFragment(container,position);
return super.instantiateItem(container, position);
}

//这个方法就是通过 Tag 来判断碎片是不是原来的,如果不是就进行替换
private void removeFragment(ViewGroup container,int index) {
String tag = getFragmentTag(container.getId(), index);
Fragment fragment = fm.findFragmentByTag(tag);
if (fragment == null)
return;
FragmentTransaction ft = fm.beginTransaction();
ft.remove(fragment);
ft.commit();
ft = null;
fm.executePendingTransactions();
}

@NonNull
@Override
public Fragment getItem(int position) {
return fragments.get(position);
}

@Override
public int getCount() {
return fragments.size();
}

//注意写成这样才可以进行刷新
@Override
public int getItemPosition(@NonNull Object object) {
return PagerAdapter.POSITION_NONE;
}

@Override
public CharSequence getPageTitle(int position) {
return page_title.get(position);
}

//禁止销毁view达到复用
@Override
public void destroyItem(@NonNull ViewGroup container, int position, @NonNull Object object) {}
//获取碎片的tag
private String getFragmentTag(int viewId, int index) {
try {
Class<FragmentPagerAdapter> cls = FragmentPagerAdapter.class;
Class<?>[] parameterTypes = { int.class, long.class };
Method method = cls.getDeclaredMethod("makeFragmentName",
parameterTypes);
method.setAccessible(true);
String tag = (String) method.invoke(this, viewId, index);
return tag;
} catch (Exception e) {
e.printStackTrace();
return "";
}
}
}

注意问题

如果出现替换后出现某个碎片的布局空白了,那就设置一个 ViewPager 的缓存属性

1
main_fragment_viewpager.setOffscreenPageLimit(4);//4代表缓存4页,根据实际情况调整

结尾

如果有代码什么问题可以向我提出

❌
❌