1823 words
9 minutes
My June in 2025
2025-07-06

回家#

五月去玩了一趟,無意中發現自己體重已經到了接受不能的程度。學校周邊實在沒法吃上淸淡的餐食,於是衹好提前跑路回家。

悲劇地,回家沒幾天導師問我科研進度,約談七月初,然後衹能厚臉皮推到八月返校之後。

回家後,每天就是吃吃睡睡,然後寫寫代碼、看各種奇怪的文章。因爲要减肥,搞了兩箇大瓶子泡冷茶、代替掉含糖飲料。


在知乎刷到箇推薦維生素D補劑的文章,查了一下好像是有點道理。買了一瓶來,開始每天吃,感覺還不錯。有種在吃抗抑鬱藥的感覺,心情變得更好了,感覺自己是老了會被推銷保健品的模樣了。()


因爲减肥離不開運動,但運動能力又很差劲,所以就選擇每天出去遛狗。她每天得陪我走个20000步以上,不過有一天晚上,有條算得上不要臉的公狗(我認爲很醜)、在她背後突然就騎了上去,我看到後都已经鎖上了,這下完了。剛好,當時她正在發情期,衹好帶她去做了絕育手術。術後七天沒法出去遛狗,這下又成了天天在家坐着。

她跟我也是很有緣的,我撿到她的時候剛好是去年七月七,那天我騎車路過公园的路口時,她跟着我的車,我便鎖了車下來走路,她就跟着我走了好久。所以我就把她抱回了家。(什麼天降情侶

Python#

因爲很喜歡 Haskell,所以在用 Python 時很心虛。

誒,如果把類型衹寫成 dict,那怎麼保證訪問的安全呢?我可不想 try-catch,也不想運行時才發現錯誤。

想到 Scala 里會定義好待解析的 JSON 結構,但這未免也太麻煩了,用腳本語言不就是圖方便(tōulǎn)嗎!

Gemini 給我推薦了一箇叫 returns 的庫,爲 Python 提供了 Result、Maybe、IO 等 Monad。

dry-python
/
returns
Waiting for api.github.com...
00K
0K
0K
Waiting...

看下面一段不安全的代碼:

import json
filename = "data.json"
# target file might not exist
with open(filename, "r", encoding="utf-8") as file:
data = json.load(file)
# entries key might not exist
entries = data["entries"]
# some entries might not have the "disabled" key
filtered_entries = {k: v for k, v in entries.items() if not v["disabled"]}
new_data = {"entries": filtered_entries}
# writing to file might fail
with open("new_" + filename, "w", encoding="utf-8") as file:
json.dump(new_data, file, ensure_ascii=False, indent=4)

使用 returns 庫可以用Result Monad來處理,而不需要手動 try-catch:

import json
from returns.result import safe
# partial application, tap for side effects
from returns.functions import partial, tap
# @safe will wrap the return value in a ResultE type and automatically handle exceptions
@safe
def read_file(filename: str) -> dict:
with open(filename, "r", encoding="utf-8") as file:
return json.load(file)
@safe
def get_entries(data: dict) -> dict:
filtered_entries = {
k: v for k, v in data["entries"].items() if not v.get("disabled", False)
}
return {"entries": filtered_entries}
@safe
# return a dict so that we can tap it
def write_file(filename: str, data: dict) -> dict:
with open(filename, "w", encoding="utf-8") as file:
json.dump(data, file, ensure_ascii=False, indent=4)
return data
filename = "data.json"
read_file(filename).bind(get_entries).bind(
partial(write_file, "new_" + filename)
).map(tap(print))

最後的 tap(print) 在 Haskell 中沒有,實際上 tap(f) 會調用 f,然後丢棄結果、返回原始的值。 x.map(tap(f)) 相當於 f <$> x *> x。(這很奇怪啊,沒人會把 fmap 的結果丢棄吧?事實上因爲副作用是 a -> m () 的類型,往往都要用 x >>= f *> x,然而 Python 中執行打印竝不會返回一箇 IO,而是 a -> (),所以 bind 就變成了 fmap )實際上這里可以用 x.map(print),因爲沒有後續計算了、所以最後返回 None 也無所謂。

這樣,沒有改變原有的代碼結構(卽無㬎式的錯誤處理),也能保證訪問的安全。

值得一提的是,在 Python 中應用 returns 提供的 IO 感覺有點怪,而且由於沒有 Transformer,想組合 IO 和其他 Monad 也不太方便。庫雖說有 ResultIO,但不如直接用 Result,因爲 ResultIO 沒法和 Result 一起方便地处理。

New Skills#

㕥前用 LaTeXLaTeX 時就不會用 tikz 畫圖,現在換到 Typst 了,學會了用 cetz。

#import "@preview/cetz:0.4.0"
#set page(height: auto, width: auto, margin: (x: 0pt, y: 10pt))
#set text(size: 10pt)
#cetz.canvas(length: 1.5cm, {
let hid = hide
import cetz.draw: *
import cetz.angle: *
let len = 4
let nline = 30
let stroke = 0.6pt
let floorStroke = 1pt
set-style(stroke: stroke)
hide(line((0, 0), (30deg, len), name: "slope"))
line((0, 0), (30deg, len), (rel: (0, -len / 2)), close: true)
line((rel: (len / 8, 0)), (-len / 8, 0), name: "floor", stroke: floorStroke)
let pos = range(1, nline + 1).map(x => x / nline * 100%)
for i in pos {
line(("floor.end", i, "floor.start"), (rel: (-0.2, -0.2)))
}
angle("slope.start", "slope.end", "floor.start", direction: "cw", name: "angle")
content((name: "angle", anchor: 15deg), [$theta$], anchor: "west", padding: 0.04)
{
rotate(z: 30deg)
rect((len * 1 / 2, 0), (rel: (len / 8, len / 8)), name: "obj")
circle("obj", radius: 0.01, fill: black)
}
set-style(mark: (end: ">", scale: 0.4), fill: black)
let len = 1
line("obj.center", (rel: (-120deg, len)), name: "G")
line("obj.center", (rel: (0, len * calc.cos(30deg))), name: "N")
line("obj.center", (rel: (len * calc.sin(30deg), 0)), name: "f")
content("G.end", [$m g$], anchor: "north")
content("N.end", [$N$], anchor: "south-east")
content("f.end", [$f$], anchor: "south-west")
set-style(fill: red, stroke: red + stroke)
line("obj.center", (rel: (0, -len * calc.cos(30deg))), name: "vG")
line("obj.center", (rel: (-len * calc.sin(30deg), 0)), name: "hG")
content("vG.end", [$m g cos theta$], anchor: "north-west")
content("hG.end", [$m g sin theta$], anchor: "north-east", padding: 0.04)
set-style(mark: none, stroke: (dash: "dashed", paint: red, thickness: stroke))
line((), "G.end")
line((), "vG.end")
})
𝜃𝑚𝑔𝑁𝑓𝑚𝑔cos𝜃𝑚𝑔sin𝜃

還可㕥畫一些莫名其妙的圖。

Dmaj7𝑎12𝑎21𝑎33𝑎11𝑎23𝑎32𝑎13𝑎22𝑎31𝑎12𝑎23𝑎31𝑎13𝑎21𝑎32𝑎11𝑎22𝑎33𝑎11𝑎21𝑎31𝑎12𝑎22𝑎32𝑎13𝑎23𝑎33000110101111101URL1URL2

然後是用 fletcher 畫 diagram(數學上主要就是交換圖):

#import "@preview/fletcher:0.5.8": *
#set page(height: auto, width: auto, margin: (x: 10pt, y: 10pt))
#diagram(
cell-size: 20mm,
let padding = -1mm,
$cal(F)(U) edge("r", phi(U), ->) edge("d", rho_(U V), ->, label-anchor: "west", label-sep: #padding) & cal(G)(U) edge("d", rho'_(U V), ->) \
cal(F)(V) edge("r", phi(V), ->) & cal(G)(V)$,
)
𝜑(𝑈)𝜌𝑈𝑉𝜌𝑈𝑉𝜑(𝑉)(𝑈)𝒢(𝑈)(𝑉)𝒢(𝑉)

最近在听#


我就算未如古跡老定

也未似幻覺初醒

離別注定了是另一種約定

偶遇那日已釐定


草 也許想能鎭定

風 也許想能安定

爲何草隨風動隨心動

爲何心無意動仍蠢動

其實那一聲我想走

早已像生死與共

不要講、講多了便無人受用

不要聽、聽多了便無人造夢


梅雨の眞ん中、今は雨上がり
生温い風、靜かな夜道を
通り抜ける、夏が近い

光り輝き、この目を奪ひ
手にしたくなる、触れてみたくなる
あなたはこの螢のよう

ふわりふわりと、宙を舞ふ螢
少し離れた場所から見るのは
一番いい、そっとそっと

あなたの気持が見えない、望むほど苦しくなる
それでも嫌いになれない

想起來這箇 よう像……一樣 的意思,來自漢字 。四川話中也有這樣的用法。另外還有一个推量的用法也是一致的。

躺着那跟个死人樣。(比況
そこに横になって、死人のようだ。

今天不得下雨樣。(推量
今、雨の降ることはないようだ。

當然,日本人竝不會這樣講話,衹是爲了對譯

不太一樣的點在於,平時「樣」這箇助詞是廣泛用在推量中的,可以有根據也可以沒有、也不限定根據是什麼。

日語里「ようだ」限定眼見、感覺爲證據,如果是傳聞則一般用「そうだ」。

喜歡的人還挺多的、這首。感覺在寫一些很私人的作品,這眞的是可以拿出來給歌迷欣賞的嗎?(想起了 Lady Gaga(bushi

Castle in the Air: “My fire turning cold”

Turn of a Page: “But my fire won’t turn cold”

My June in 2025
https://blog.orbitoo.top/posts/thoughts/25-06/
Author
Orbitoo
Published at
2025-07-06
License
CC BY-NC-SA 4.0