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𝜃

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

D♭maj7−𝑎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
Written by a human, not by AI