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

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
Forwarded from dnaugsuz
在 suspend fun 里引用啊(迫真
其实 suspend 的 closure 也可以,runBlocking 什么的……
协程不熟悉…… 我真的该多看书
Forwarded from dnaugsuz
怎么感觉你是想用 operator … unaryPlus()+MHE.ping…… 如果是局部的话应该就不能引用吧……
Forwarded from dnaugsuz
强烈推荐陈光剑的《Kotlin 极简教程》
对 Coroutine 讲得也很细
Forwarded from dnaugsuz
是指 +(::susFunc as /*suspend*/T.() -> Unit) 这样的,receiver 是为了调用 () -> Unitoperator unaryPlus

参数化多态再加上 bound 什么的看起来有点混乱,其实有时候感觉还是蛮有用的,毕竟可能最大限度泛化代码,而不止是 subtyping

> 一般带 receiver 的 lambda 是作为参数指定类型的吧,然后一般扩展函数的 receiver 用匿名类型,使用起来也会很别扭吧
(1) 的确是用来指定 receiver 的类型,虽然我相信很多人第一眼看到 init: A.() -> Unit … { (x as A).init() } 都会觉得很扎眼:咦? init 为什么跑到中间来了?
(2) 没看出来 MHE 是类型变量…… 泛化的话应该是可以用吧……
扩展函数定义类似 fun List<T>.sum() where T: … 这样的会很有用
Forwarded from dnaugsuz
好像只要 main thread 死了 JVM 也会 exit?之前在周志明《JVM 最佳实践》上好像看过似乎是 main thread 一死就全瓜瓜了
duangsuse::Echo
10_12
想今天先做 (2) 和 (3) 的一部分、(10) 🤔 我还是很想完成 Doku 库的,毕竟是一血前耻
a2i2a.cpp
1.3 KB
浪费了我很多时间,教会了我,其实有些东西不一定是你开始想的那样,然后是要懂得接受失败, 🙃 #CXX #Algorithm, 这个算法还是要写,不过明天要先纠正下理论的错误
duangsuse::Echo
a2i2a.cpp
咳咳,理论上呢…… 我昨天晚上洗澡的时候想到了,其实在我看到之前的设想失败时

一言以蔽之,就是我重新(当然是独立地)发明了取余进制换算……

开始我的思路是利用除法去取 (base**) n 位的数字 k (= rest / ones),比如给 100 的时候,我取 10**1 位 (100 / 10) = 10 也就是说第二位是 "10",我当时居然还觉得很正常,全然不顾它不在 (0, 10] 区间内了 🤪

直到不断 segfault 我才开始思考,于是就这样乱改代码(我也不会用 GDB,连 segv 的时候是哪一行我都问不出来,where 没用、info 太多、tstack 没用、show,list 的不是……)
我一直以为错在 CString 构造失败(存在末尾 \0 的问题),我怀疑是我把索引计算错了,所以就一直在 lstr-1, lstr-2 之间徘徊……(当然子程序只是要你给 nstr, 字符串长度……)

因为之前的这种智障想法,我甚至以为 XXXXX(eo {N+}) / base(=10) 就可以得到它的十进制长度…… 其实只是因为我举例子的时候全举的是 (10**n) 这种特例,然后我居然信了…… 😂
现在改成了浮点数(其实也可以用 !=0; /base 循环,不过还是开对数 lg 好) round(log10(n))+1 或者 ceil(log(n, base)) (肯定要 ceil,因为是开幂啊,只要有零头就是 1002 这类)
为了『修正』这个实际上是算法的问题,我祖传(其实真的不想用的,我不想面向 REPL 编程,很脑残)的 cout « 就开始了…… 结果当然是无功而返,碰了一鼻子灰,而且我甚至连 radare2 pd 都用上了,segv 的时候它在 movzx eax, byte [rax], 我不知道是在干什么(大概是在解引用 char* 吧)

所以我看到 1024 / 10 (/=2; =102) 的时候,绝对是崩溃的 😭
不过还好我立刻想到了:如果我用 1024 mod 10,就可以拿到第一位的 4 了,即便差了一位效果一样(于此同时我还想了被我否决的 (rest/base)-(rest%base) 等一大堆脑残思路)

于是,我可以写这个 #Haskell 程序

module Atoitoa(atoi, itoa) where
import Data.Char (digitToInt)

radix_K16 = "0123456789ABCDEF"
radix_K10 = take 10 radix_K16
radix_K2 = take 2 radix_K16

-- F**king GHC won't accept (itoa'' rx k0 k 0) branch
itoa'' rx k0 k n
|n == 0 = []
|otherwise = let d = (n `mod` k) in
(rx !! dIdx d) : itoa'' rx k0 (k * k) (n - d)
where
lastk = k `div` k0 -- k=1000, lastk=100
dIdx d = (d `div` lastk)

itoa' radix base = reverse . (itoa'' radix base base)

itoa = itoa' radix_K10 10
itoa_2 = itoa' radix_K2 2
itoa_16 = itoa' radix_K16 16
atoi base = foldl (\ac -> (ac*base +) . digitToInt) 0

我调试了半天,想了很久,但还是有问题
3 = 0b11
4 = 0b100
可为什么 itoa_2 = "000"
看来我之前想得还不假…… NP,真的是 to_ss 把我搞糊涂了…… char show[] 的 +1 不应该算在 nstr 里面,因为 to_ss 显然小于 actual size……
[DuangSUSE@duangsuse]~/Projects/Share/Others% ./a.out
123456789
5
10086
🤔 虽然我花了很多时间而且并不干净利落,但总感觉还是有所收获……
char show[nstr+1] = {'\0'};
我知道了,这样分配的话字符串的最后索引就是 nstr-1, 不算 NUL char 的长度
而不是
char show[nstr_pnul] = {'\0'};
write_to_str(show, nstr_pnul-1/*NUL*/);

实现了 itoa :: Int -> String
开始我天真地以为 123 / 100 == 2…… 于是就很简单 后来终于明白了,不是 🤪
后来我是这种思路:
units = 10**1, 10**2, 10**3…
ds = n mod units[0], n-ds[0] mod units[1], …

看起来 n = 123 的时候,ds 就是
ds == [3, (123-3) mod 100 (= 20), (120-20) mod 1000 (= 100)]
实现的时候我写错了(或许),好吧

lastks = 10**0 ++ units
这样我再去 (/ lastk) 就可以得到
ds' == [3, 2, 1]
可是事与愿违,我也不知道为什么就不行。
还好我有 bitwise ops 的『数值分割』式觉悟,立刻换成了 /base | %base 这样的高效方法 (滑稽)

import Test.QuickCheck (quickCheck)
import Data.Char (intToDigit)

itoa'' :: Int -> (Int -> String)
itoa'' b n
|n == 0 = []
|otherwise = intToDigit (n `mod` b) : itoa'' b (n `div` b)
itoa' base = reverse . (itoa'' base)

itoa = itoa' 10
prop_itoaEquiv i = if i>0 then
(itoa i) == (show i) else True
where _ = i :: Int

🤔*Main> quickCheck prop_itoaEquiv
+++ OK, passed 100 tests.
最近已经越来越蠢了……
import Test.QuickCheck (quickCheck)
import Data.Char (intToDigit)

itoa'' :: Int -> (Int -> String)
itoa'' b n
|n == 0 = []
|otherwise = intToDigit (n `mod` b) : itoa'' b (n `div` b)
itoa' _ 0 = "0"
itoa' base n = let f = reverse . (itoa'' base) . abs in (f n)
fneg toa n = let s = toa n in
if n < 0 then '-' : s else s

itoa = fneg (itoa' 10)
prop_itoaEquiv i = (itoa i) == (show i)
where _ = i :: Int


考虑一下 123(10),如何换算为 16 进制呢?
就是不断 (rec div) + digit mod…
(123/16)%16 (=7) + 123%16 (=11)
最终得 d 7 + d 11 == "7b"

说白了就是 10 进制的 bitwise shr, and,当然这个 itoa 在 base=2 的时候也有效
二进制的『位运算优化』之所以 n << (k) == n / (log2 k) (比如 10/4 == 10 >> 2,当然反过来也一样,而且反对称的 << 也能套)
<< 运算符是有可累积性的(a << (b+c) = a << b << c)

0b011 <- shr 移动一位,任何的 2**n 就变成了 2**(n+1);这里 0b1 变成了 0b10 (10-1 = 1)、0b10 也变为 0b100 (100-10 = 2)
所以说整个都变成 2 的 (log2 k) 次方

90 & 0b1010(10) 二进制的时候是特例,不需要 mod 都可以计算,但是十进制不行,我也不知道为什么
duangsuse::Echo
a2i2a.cpp
那么这件事就告一段落啦 #Algorithm #Haskell #Math #CXX 🤔

module Atoitoa (atoi', itoa') where
import Data.Char (digitToInt)

type Radix = [Char]
type Base = Int

atoi' :: Base -> (String -> Int)
atoi' b = foldl (\ac -> (ac*b +) . digitToInt) 0

itoa' :: Radix -> Base -> (Int -> String)
itoa' rx b = reverse . (itoa'' rx b)
where
itoa'' _ _ 0 = []
itoa'' rx b n = let c = rx !! (n `mod` b) in
c : itoa'' rx b (n `div` b)
Forwarded from duangsuse Throws
https://www.eet-china.com/news/201907231509.html #Huawei 🤔

#life #China #recommended
在《第一时间》杂志上看到一个无线通讯的天才少年,推荐过来
申怡飞 (文)
当然,其实关于这个『天才』是不是一定要『少年』呢…… 其实一般个人会有个人的看法
国家之前特别弄过『少年班』的,可是发现这样出产低,而且会浪费一些不是极端优秀但很不错的人,出产的天才少年也未必比其他天才好很多

这个人是独立弄的,所以的确是从小就天才。

当然,现在揠苗助长的事情实际上还有一些,比如那个考上大专(通过高考)的十岁女孩……
按照这位父亲的看法,中国的教育肯定辱没了很多『天才少年』
可是刻意要生造出那么多天才少年干什么呢……

我个人非常想当一个天才,因为天才意味着…… 我不仅有很强大的计算和抽象、组织能力,而且还很快…… 不会错…… 可是终究不是天才,我要花很多时间来完成简单的事情,太可惜了(虽然一般来说天才是极少的)
而且这样的话我就可以更快地开始学信号处理和机器学习了,这两者对数学能力有要求,所以还不是很熟悉。
Forwarded from duangsuse Throws
#statement #Qzone
新的 bio !(应该就在 suse 的空间里,下一条)

原 bio 是 「Technical unfamiliar is the root of all evil 菜是万恶之源」

这句话是从《爱丽丝梦游仙境》的对话里提取出来的理念

没头脑的拼死拼活、无目标的吃苦。为何而活?相信至少都是为不想死而活,可是活着要干什么呢?
为了获得别人的称赞、小小的优越感?为了搬家到大城市?

我想先为自己而活,为了别人对我的看法,我活得太累。群众的眼睛也未必是雪亮的,更多是无知和盲从。

偶尔在调试程序的时候,即便连调试器都不会用,想着因为有 bug 而 debug、面向 REPL 编程,越来越觉得我不该死脑筋了
王垠会批判部分 Haskell 程序猿「从不调试程序,因为根本不写 bug」的论调,可我觉得这话就莫名正确,如果不知道自己干了什么,不如退出去好好想想,再做决定,而不是无意义地歇斯底里,最终一事无成。

人们对待失败的做法不同,所以才会存在一败涂地和反败为胜的区别;脑子是好东西,可不是所有人所有时候都能尽可能好地利用它。

有些程序员经常把「不知道自己在干什么」挂在嘴边批评别人,想想也真是句有意思的话吧……
duangsuse::Echo
10_12
人 性 泯 灭
抛弃未做…… 也要写 Doku 库
就为了弄个 AXML 读写库
人 间 失 格 编程 连 续 8 小 时;只为一些无聊的位图处理……
Montage.py
9.9 KB
Monavatar.jpg.png
125.3 KB
duangsuse::Echo
人 间 失 格 编程 连 续 8 小 时;只为一些无聊的位图处理……
This media is not supported in your browser
VIEW IN TELEGRAM
悲惨的起因,只是因为在 GitHub 上看到别人有用 Python+Pillow 写这个:

https://github.com/FerryYoungFan/SimpleTextMontage

虽然数学不好,对某些关系不那么扁平的数据处理也会非常吃力的 duangsuse 就头脑发热地想:

『这么简单的程序,我怎么可能不会写?我一定要写出来看看』

结果就杯具…… 😭 不过还是有一点收获,就是我学会了如何用 color average 插值写位图 scale 算法
虽然花了我至少 6 个小时的时间才完成到可以生成图片(本来应该只要一个小时,可是被 argparse 坑了…… 我不该一上来就填那么多参数),但感觉也还可以,而且我没有在任何关键问题上查资料,也没有看太多次 help
学习还是有效果的,毕竟我学会了这些 API:

Image.open(path)
Image.new(space, coord, fill)
Image#width, Image#height
Image#convert(space)
Image#getpixel(p) -> tuple
Image#setpixel(p, tuple)
ImageDraw.Draw(img: Image)
Draw#text(p, txt, font=, fill=)
ImageFont.load_path(path)
ImageFont.truetype(name, size=fntsz)
ImageFont.FreeTypeFont

当然一般来说为了性能(其实当然在 DIP 的时候算法是最重要的)都直接用 JVM 的 awt.BufferedImage 吧……

javap javax.imageio.ImageIO
javap java.awt.image.BufferedImage


我的 Gist 上有 Kotlin 字符画 ASCII Art 生成器的源码

看了 FerryYoungFan 的版本,10:52-11:27 花了半个多小时,好像不是提前写好了的,唉

算法上,除了 [xs[k:(k+2)] for k in (0,2,4)] 这种没见过(也不是不会写)都知道
不过设计上,没有扣像、 (keyColor, keyThres, keyRatio) 、自动渐变的背景色 (刚才我以为 count avgcolor 是拿来判断背景色的…) 和 xy padding (w- colPxs*m) /2
也没有加 textVsp 和 textHsp 文字间距,和图像边角的间距,我的版本写的更活一点,不过大概是没有太大意义的……

另外 (keyColor, keyThres), keyRatio 我还是会写的,之前的 Kotlin ASCII Art 就用到了 filter 色值的算法;只不过这个是按照 abs 符合要求色块数目来取舍是否生成文字

如果我使用高效的 Numpy/Pillow 内建函数,而不是我手动的 average 插值 scale 算法(Montage.clippy) 的话,就可以拿来处理视频(否则太慢了,处理不过来),实际上 B 站也有一个罗小黑战绩《晚安喵》的这种视频,有心人不妨试试重构。

#Python #tools #DIP