duangsuse::Echo
717 subscribers
4.25K photos
130 videos
583 files
6.47K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
🙃 谁能给我解释一下这是什么意思?在没有任何通知的情况下,我因为发了几个『政治相关内容(关于六四事件政府方面的两本书)』、说了一句『保持看戏,静观其变』就被移除了,WeVoice,真是名副其实,和它其中大部分成员所批判的大陆政治状态一样,『言论自由』『法制和谐』,自己打了自己的脸。
duangsuse::Echo
🙃 谁能给我解释一下这是什么意思?在没有任何通知的情况下,我因为发了几个『政治相关内容(关于六四事件政府方面的两本书)』、说了一句『保持看戏,静观其变』就被移除了,WeVoice,真是名副其实,和它其中大部分成员所批判的大陆政治状态一样,『言论自由』『法制和谐』,自己打了自己的脸。
愿意的可以到 @weVoice4Future 帮我问问是怎么回事 #life #China #Low #Telegram

这就是我的观点,而且我没有人身攻击任何一群人、我没批评任何一种思潮。
Birds of a feather flock together. 曾经是,因为我没有说对『香港自由运动』不利的话。
We』的『Voice』原来就是集锦一群人的声音,一群『核心价值观』毫无差别的人的声音,所以是来加群热闹找存在感的。
和 PRC 的政府一样,它自然也得竭尽所能 filter 掉那些不同的声音喽,原来是我太天真了。真棒。
— until the cat comes.

政治本身是没有用的,有用的是它对生产生活的疏导维护作用。
政治是操作系统、是服务程序、是公开平台,但是真正给人用的,让人叫好的,是面向最终用户的应用程序!
是人们的工作、生活、娱乐!不是选举、执政、演讲、示威、暴力、拉票、水军、信息渠道污染!不是和希特勒一样成天『鼓舞民愤』,满天放烟花。
嗯,烟花的确很好看,不要阻挡我观赏它。🙃 也不要阻挡我赞叹它的美丽,我和你们 — 从做为上看是一样的。

政治环境很重要,可惜,很多人根本意识不到就算是在大陆,自己也未必就是对政治『束手无策』的。

编程随想浩哥ShadowSocks 项目的众多维护者、韩寒,他们都是很好的例子,可惜有些人放弃的太早了,看到的太近了,以至于对整个中国的『现况』丧失了希望。
是的,除了无止境的批判,然后在自己的生活中,做得和自己所批判的东西一样 — 别无二致。

我爱自由,甚至作为一个不称职的高中生,我本身都自由到放弃课业选择编程了,即便它不够『标准』。
可是我还没有自由到不分黑白也要追求一个定义不清的“自由”。

这才是我看戏的原因,为什么?谁来回答我,root cause 是什么?事情是因为什么而起,又是什么使得它成为现在这个样子的?是哪些人以何种目的在推动?最终目的是什么?怎么处理现在的问题?
如果你的回答是旁观或者在某个 Telegram 频道上说几句实际上没人听的话 — 恭喜,其实我们是一家人了。

这很好、这对现况有帮助、这很自由,是所有人需要的自由,或者它才是要葬送中国未来的想法吧。
Forwarded from 永久封存 | Yuuta 台 | 😷 #Pray4Wuhan (Yuuta⠀)
香港闹的事,已经分不清黑白了。我决定不再关注这件事情。

反送中到暴力,再到一味冲击警察,再到中国的疯狗式宣传。

我的立场(如果打不开请先从 t.me/Trumeet 关注本台): https://t.me/c/1076844146/9118 ,我觉得还是挺中肯的(貌似)

现在已经不是反送中了,我也没有关注下去的必要。希望不要成为下一个六四,希望香港残缺的民主和一国两制还能延续几天,好歹 50 年,不是吗?

还有件事,那些举着别的国家国旗游行的,到底是想做点什么呢..

欢迎你转发和讨论。如果就此说我是所谓五毛粉蛆,或者所谓反动分子,那是你们的非黑即白。

本台 ID: t.me/Trumeet
duangsuse::Echo
#question 🤔 有一个问题困扰了我很久 2017 - 2019, 两年多了。 为什么我无数次跌下绝望之谷,却始终未能爬上开悟之坡 为什么我觉得自己越来越菜了
下面会解释一下原因,并且谈及 DOM h1-h6 文档 heading 树解析的问题
哈哈哈哈 😂 笑死我了
Forwarded from duangsuse Throws
duangsuse::Echo
下面会解释一下原因,并且谈及 DOM h1-h6 文档 heading 树解析的问题
解释:最近因为 某些不可预期也不可回避的原因 我不仅仅咸鱼,而且还忘记了很多希望能讲的事情...
部分原因也是『讲』开始不够了,好了... 接下来 部分回归正轨
Forwarded from duangsuse Throws
公告表示此为 Telegram 机器人对特地消息排版模式的误封锁
此时误会已经解除,对 WeVoice 管理员之前的误解表示抱歉
Forwarded from 久违了,weVoice 资讯 | 咕咕咕咕咕咕
#未公告
占用一下 News 的空间来声明一下昨天 @duangsuse 被无故封锁一事。
此封锁操作由 TGCN-ADNK 机器人错误发起,项目组反馈如上。当事人没有任何违背群规行为。
🤔 这时候我还有一点在想 ADNK 是啥子的缩写
duangsuse::Echo
解释:最近因为 某些不可预期也不可回避的原因 我不仅仅咸鱼,而且还忘记了很多希望能讲的事情... 部分原因也是『讲』开始不够了,好了... 接下来 部分回归正轨
为什么会觉得自己变蠢了:

1. 我本来就不够聪明,相对于我想做的事情而言
2. 我缺少练习,最近也缺少动力(即便事情越来越多,但对慵懒的我来说,事情越多我越推,少一点我反而干了)
3. 三天打鱼两天晒网(至少最近是如此)的模式是不利于发展的
4. 最近的需求提升太剧烈了,具体表现:
a. 我比以往更重视编程实践和(非易失)状态化编程了,这样就不得不谈数据的表示方式(序列化)和一堆问题,我还要接触 C++ 的 iterator, fstream, map, string 什么的东西
以及,Maven, Gradle 等构建工具的语法和 Make 有很大差别,而且多数插件配置繁多
以及,越来越多开发者开始学习 Kotlin Common / Multiplatform / C / C# 了,我怕是跟不上,何况他们的插件也有一大堆配置和 properties
b. 我开始看网络编程了,虽然都是应用层的,而且表示全是 HTTP,最重要的是我同时考虑前端的问题,单页路由好像没有去了解,有时候设计我不会的 layout 就会出问题,Android 应用的标准开发模式也不熟悉
最重要的是,我对 box layout 不了解...
c. 击键不熟悉、创建项目变少、看见大佬的项目和 production ready / 技术高超的软件变多,导致信心丢失严重
d. 我的『分析』更频繁了,而且全都是不会写出来的那种
da. 比如,我看到 zuobiao.me 的调查表都会思考其分页调查实现方式,状态数据传递方式
我会考虑给予一个 [Int], 如何统计出各元素出现的数目,而且最重要的是我不会只想一种方法(比如上面的问题,我基于过程式给出了直接对每项统计输出/array 的做法、基于函数式 map & count、基于算法使用 Map 结构)
甚至对同样的方法我都要想多种范式的(过程式、函数式、多范式封装方式),这占用了大量的脑力和零碎时间
偶尔还会考虑相关的 API 封装方式(比如上例,数据『座标』图的绘制接口,而且还得翻找之前的经验,又得等半天)
db. 比如,知道自己是被 CNBLR 的 ADNK bot 封禁以后,我得考虑类似的 bot 是如何实现(事件模型),需要何种作用域下的何种状态
哪怕是『黑名单和白名单模式,怎么实现』这个问题我都得想一分钟,最后找到如下程序:
       def acceptable(item):
if use_whitelist: return item in acceptables
else: return item not in acceptables

not = lambda p: lambda x: not p(x)
elem = lambda x, set: x in set
notElem = not(elem)
def acceptable1(item):
judge = elem if use_whitelist else notElem
return judge(item, acceptables)

这还没完,我得继续找下去(实际上因为很久没看书,我的直觉下降了很多,连这个 def acceptable 定义的类型签名我都想了一会)...
我找到的很多程序都只是一个(不一定是最好的)版本而已,本身还可以有很多方式写出等价的程序
            def acceptable2(item):
accept = item in acceptables
if not use_blacklist: accept = not accept
return accept

我甚至回忆起了 Scheme (准确的说是 Racket... R6RS 好像没有 Map 吧?)...
       (define (count words)
(set! counts (make-hash))
(for-each words (lambda (w)
(hash-update counts w (+ (hash-ref counts w) 1) 0) )))

dc. 有时候我得看一些不那么直白的代码,得想『还能怎么做』,比如之前重构的 FontMod... (和其作者交流了好久,快把 @YuutaW 刷屏了,跑)
想不明白的问题多了自然觉得自己菜了....
duangsuse::Echo
解释:最近因为 某些不可预期也不可回避的原因 我不仅仅咸鱼,而且还忘记了很多希望能讲的事情... 部分原因也是『讲』开始不够了,好了... 接下来 部分回归正轨
下面来说一下这个基于 DOM 的 Heading tree 解析程序的问题 #JS #Algorithm
你将学会如何在使用显式递归的情况下,只用栈数据结构该如何解析提取嵌套结构

一个明显的好处是这么做快一些:在构造部分子树时,不需要判断 N 次基线条件
此外,这样无须使用 iterator 来跨子程序传递流(扫描)状态
一个坏处是:程序没有那么优雅好看了

接下来讲的实现方式包含三种:

1. 标准方式 — Iterator
a. 把 iterator 的 position 放在递归参数里
b. plain iterator
2. “普通”方式 — 无限 subsequence
我就不写了... 其实很多人这么写的时候也是递归地构造结构,而且对这个问题这么做尤其莫名其妙
3. 优化方式 — foreach 状态机 + 两个显式栈
其中一个栈是用于保存 Heading 深度的,一个栈是保存结果的,只不过碰巧也可以用栈的方式实现
const _1to6 = '1,2,3,4,5,6'.split(',');
function parseHeadingTree(root) {
const isHeading = e => (nm => nm.length > 1 && nm[0] === 'H' && nm[1] in _1to6)(e.tagName);
const headingDepth = e => Number.parseInt(e.tagName[1]); // why not regex?
const peek = (xs) => xs[xs.length -1];
/**/let resultstk = [[]], depthstk = [1]; // 2 stack
for (let elem of root.children) {
if (!isHeading(elem)) continue;
let depth = headingDepth(elem);
let lastdept = peek(depthstk);
if (depth > lastdept) {
depthstk.push(depth);
let subtree = [];
peek(resultstk).push(subtree);
resultstk.push(subtree); }
else if (depth < lastdept) {
depthstk.pop();
resultstk.pop(); }
peek(resultstk).push(elem);
}
return resultstk;
}

发实现走人(慵懒
... 我还打算一遍过的,没想到我对栈组织的还好,对结果的断言没预料到.... 我想想
不过也很快了,程序总共只修改了两次就可以勉强按照预期运行,而且两次
1. 我的一个注释写成了 /*/
2. 我测试的时候给的 document.body 没有 heading
const _1to6 = '1,2,3,4,5,6'.split(',');
const isHeading = e => (nm => nm.length > 1 && nm[0] === 'H' && nm[1] in _1to6)(e.tagName);
const headingDepth = e => Number.parseInt(e.tagName[1]); // why not regex?
const peek = (xs) => xs[xs.length -1];
function parseHeadingTree(root) {
let resultstk = [[]], depthstk = [1];
for (let elem of root.children) {
if (!isHeading(elem)) continue;
let depth = headingDepth(elem);
let lastdept = peek(depthstk), leaf = peek(resultstk);
if (depth > lastdept) {
depthstk.push(depth);
let subtree = [];
leaf.push(subtree);
resultstk.push(subtree); continue; }
else if (depth < lastdept) {
depthstk.pop(); resultstk.pop(); }
leaf.push(elem);
}
return resultstk;
}
争取一下,模拟执行发现一个 bug...
其实我没有主意到 leaf (本身是一个 expression,而不是 value)在过程中发生了更新(if (depth < lastdept) { resultstk.pop(); }
看来 JS 里没法解决了... 哦不我用箭头函数

至于剩下的问题,就是『栈上重复的引用』
返回前加一个 pop 即可解决
我日,这反 修复失败...
duangsuse::Echo
我日,这反 修复失败...
function parseHeadingTree(root) {
const topItem2Stk = (xs) => { let top = xs.pop(); xs.push([top]); };
const deepest = (xs) => { let xx; for (xx = xs; xx.length >0 && xx[0] instanceof Array; xx = xx[0]); return xx; };
let resultstk = [[]], depthstk = [1];
for (let elem of root.children) {
if (!isHeading(elem)) continue;
let depth = headingDepth(elem);
let lastdept = peek(depthstk), leaf = () => peek(resultstk);
if (depth > lastdept) {
depthstk.push(depth);
let subtree = [];
topItem2Stk(resultstk);
leaf().push(subtree);
resultstk.push(subtree); }
else if (depth < lastdept) {
depthstk.pop(); resultstk.pop(); }
leaf().push(elem);
}
let layer = peek(resultstk);
while (layer instanceof Array &&
(layer.length === 0 ||
headingDepth(deepest(layer)) !== 1) ) {
resultstk.pop();
layer = peek(resultstk); } // for top <h1>
return resultstk;
}


为什么一定要 pop 到 <h1>?因为普通情况:

<h1/>
<h2/>
此时栈顶依然是 h2 的子节点,除非它后面跟了个 h1 使得它被关掉
length == 0 的是不合法的情况,每层至少得有一个 <hn>
len=0 说明它是在读取一个 subtree