#1053 荷兰手写邮票

2024-12-26

Postzegelcode

A postzegelcode is a hand-written method of franking in the Netherlands. It consists of a code containing nine numbers and letters that customers can purchase online from PostNL and write directly on their piece of mail within five days as proof of payment in place of a postage stamp.
Postzegelcode 是荷兰的一种手写邮资盖章方法。它由一个包含九个数字和字母的代码组成,客户可以从 PostNL 在线购买,并在五天内直接写在邮件上,以代替邮票作为付款证明。

For mail within the Netherlands, the nine letters and numbers are written in a three-by-three grid. For international mail there is a fourth additional row that contains P, N, L.
对于荷兰境内的邮件,九个字母和数字以三乘三的网格形式书写。对于国际邮件,还有第四行,其中包含 P、N、L。

The system was started in 2013. Initially the postzegelcode was more expensive than a stamp because additional handling systems were required. Then for a while the postzegelcode was cheaper. Eventually the rates were set to the same price.
该系统于 2013 年启动。最初,postzegelcode 比邮票更贵,因为需要额外的处理系统。后来有一段时间,postzegelcode 更便宜。最终费率被设定为相同的价格。

In December 2020, 590,000 people sent cards with postzegelcodes.
2020 年 12 月,有 590,000 人使用 postzegelcode 寄出了卡片。

Safety 安全

Since the codes are valid for only five days, the chance that someone would guess a recently purchased code is quite low. Assuming 26 letters and 9 digits (the zero is not used to avoid confusion with the letter O), there are 35 (78.8 trillion) possibilities. Even if a postzegelcode were used for all mail items in the Netherlands, the probability is about 1 in 2 million that any stamp code has been sold in the past five days.
由于代码有效期仅为五天,因此有人猜出最近购买的代码的可能性非常低。假设有 26 个字母和 9 个数字(不使用零以避免与字母 O 混淆),则有 35(78.8 万亿)种可能性。即使荷兰所有邮件都使用 postzegelcode,过去五天内任何邮票代码被出售的概率也约为 200 万分之一。

import random
import string

# 不使用零以避免与字母 O 混淆
CHARACTERS = string.ascii_uppercase + '123456789'

def generate_postzegelcode(international=False):
    # 随机选择 9 个字符
    code = ''.join(random.choice(CHARACTERS) for _ in range(9))

    # 如果是国际邮件,添加额外的一行 "PNL"
    if international:
        code += 'PNL'

    # 按照网格格式展示国内邮件的编码
    grid = [code[i:i+3] for i in range(0, len(code), 3)]

    # 返回邮票编码,按网格排列
    return '-'.join(grid)

#1052 Clean Architecture 深得我心

2024-12-11

核心思想一般都总结成:关注点分离,依赖反转。
我理解就是:
程序的核心部分是业务逻辑,业务逻辑应该是清晰准确的表达。
业务逻辑应该和实现细节彻底隔离,避免业务逻辑受到实现细节调整的影响。

  1. 框架隔离:业务逻辑和框架解耦,无论切换到什么框架,业务逻辑无需变化
  2. UI 隔离:无论使用什么 UI,Web UI 也好,某个图形库也好,命令行也好,业务逻辑无需变化
  3. 数据库隔离:切换数据库的成本就是封装外围数据操作接口,业务逻辑无需变化
  4. 外部依赖隔离:外部依赖提供的功能被封装,切换依赖也不会影响到业务逻辑

我就觉得应该通过分层,封装,最终的核心逻辑应该是非常简练的一段代码,就好像把大象装冰箱一样简单:打开冰箱,把大象放进去,关上冰箱。

好处是:

  1. 代码结构清晰整洁,容易阅读,容易测试,容易维护
  2. 核心逻辑简单明确,稳定可靠,不容易出严重问题
  3. 方便调整外部实现,更加灵活

核心概念与实现

  1. Entities(实体层)
    代表业务核心规则或领域模型,纯粹的对象,不依赖其他层。这一层的职责是定义系统的业务规则,保证其独立性和复用性。

  2. Use Cases(用例层)
    定义具体的业务流程,协调 Entities 来完成系统的功能需求。这一层负责系统的行为逻辑,并确保业务规则得以正确执行。

  3. Interface Adapters(接口适配器层)
    负责将外部世界的数据转化为系统可以理解的形式,或者将系统的数据转化为外部需要的形式。这一层包括控制器、Presenter 和 ViewModel。

  4. Frameworks & Drivers(框架与驱动层)
    最外层,包含数据库、UI、第三方服务等实现细节。它们是可替换的,不影响核心业务逻辑。

实现的三个关键原则

  1. 依赖规则(Dependency Rule)
    依赖只能指向内层,外层不能直接调用内层的实现。通过依赖反转原则(DIP),核心业务逻辑完全摆脱了对实现细节的依赖。

  2. 边界抽象(Boundary Abstraction)
    内层通过接口定义与外层的交互边界,外层实现这些接口。这样,业务逻辑可以独立于外部框架或工具运行。

  3. 测试友好性(Testability)
    因为核心逻辑不依赖外部框架或技术,单元测试可以专注于纯粹的业务逻辑,减少测试复杂度。

#1051 与人沟通容易犯的两个错误

2024-12-04

过去一年的工作中,与人沟通越来越重要,让我注意到这个沟通效率问题。
我进行了一点总结,沟通低效是个普遍存在的问题,以下是两种常见的情形:

首先,有些人倾向于沉浸在自己的感受中,注意力更多放在自己想要表达的事项上。
这种“自我表达导向”的沟通方式,常常忽略了倾听的重要性。对方的观点和需求没有被充分理解,容易导致信息传递失真,甚至引发误解或冲突。

其次,思维跳跃问题也是沟通低效的一个重要因素。
在讨论中,思维发散,想到哪里说到哪里,无法聚焦于核心问题。这种“漫无目的”的沟通方式,不仅容易让对话变得冗长,还可能让其他人难以跟上节奏,最终导致问题久谈不决。

沟通效率的提升需要自我觉察和刻意练习,需要用心听别人的观点,然后把注意力放在这次沟通的主题上。

#1050 BFCM 是什么

2024-12-03

黑五(Black Friday)指的是美国感恩节后的一天,标志着圣诞购物季的开始,通常有大幅折扣。
网一(Cyber Monday)是紧接着黑五后的周一,主要针对线上购物的促销日。
BFCM(Black Friday Cyber Monday)则是指黑五和网一的联合促销活动,通常涵盖这两天的折扣。

在2024年,黑五(Black Friday)是11月29日,而网一(Cyber Monday)是12月2日。
BFCM(Black Friday Cyber Monday)通常指的是这两天的促销活动,涵盖了从11月29日(黑五)到12月2日(网一)的整个周末。

#1049 使用 ffmpeg 从视频中提取与合并音频信号

2024-11-28
# 提取音频
ffmpeg -i 夏洛的网_中文.mp4 -q:a 0 -map a 夏洛的网_中文.mp3

# 合并音频
ffmpeg -i 夏洛的网_英语.mp4 -i 夏洛的网_中文.mp3 -map 0:v -map 1:a -map 0:a -c:v copy -c:a copy 夏洛的网.mp4

# 给不同音轨取个名字
ffmpeg -i 夏洛的网2.mp4 -map 0 -c copy -metadata:s:a:0 title="中文" -metadata:s:a:1 title="English" 夏洛的网3.mp4

# 添加字幕(总是报错,没有成功)
ffmpeg -i 夏洛的网3.mp4 -i 夏洛的网_中文.srt -i 夏洛的网_英文.srt -map 0 -map 1 -map 2 -c:v copy -c:a copy -c:s srt \
-metadata:s:s:0 language=chi -metadata:s:s:0 title="中文" \
-metadata:s:s:1 language=eng -metadata:s:s:1 title="English" \
夏洛的网4.mp4

虽然字幕没有成功,但是播放器会自动加载,也还好。
PS:字幕其实也是播放器自动在线匹配,然后我选择保存在本地的。