昨天突发奇想想总结一下2022年, 发现还是用mermaid的甘特图做最简单. 鼓捣一番以后在朋友圈里发了这张图:

今天简单总结一下mermaid的甘特图(gantt chart)语法, 因为昨天感觉mermaid官网的gantt文档 只给了几个例子 不太适合上手.

mermaid.js

mermaid.js是一个用来在网页中生成图表的库. 使用简单的语法来描述图表, 通过 JavaScript渲染.

支持生成多种类型的图表, 例如流程图/时序图/甘特图等等.

Mermaid.js 的目标是让生成图表变得简单而且易于使用, 让用户能够更专注于图表的内容和信息的传递而不是图表的排版.

它的理念和markdown/graphviz一样, 用代码代替富文本(word/powerpoint/画图工具), 这样做的好处有:
- 文件超小(只是文本文件), 打开和修改很方便
- 生成的图片是SVG, 不但美观还可以无损缩放
- 方便版本管理(git)

之前我试过mermaid的流程图(flow chart), 感觉不如graphviz灵活(虽然语法更简洁). 但是mermaid被许多markdown编辑器支持, 而且覆盖了很多类型的图表 ...

前一阵考过了KDE的德语B1/A2考试, 我和老婆一致认为这可能是最水的德语考试. 简单总结一下考试经验.

学德语的误区

之前断断续续在Swissing上了两三年的德语课, 但是一直没敢去考试. 原因有三:

1) 平时上课不咋认真, 一周一次课的效果很差(作业没咋做, 过一周就忘了);
2) 总感觉德语的语法太复杂了, 各种时态语态后缀, 搭配单词的阴阳中性总是记不住, 平时德语小测的成绩也一般;
3) 感觉标准的TELC/Goethe考试难度很大.

而真实的情况是:

1) 与其每周被动的上课听老师讲, 其实有更有效更实用的学德语方法(后面讲), 断断续续学一年的效果很可能不如突击两三个周末;
2) 平时德语课的小测注重的是语法点, 实际上对于考试而言, 语法是最不重要的, 而主要在于是否能够理解日常对话/阅读场景. 与其花时间记忆词性/时态的各种"转换矩阵", 增加词汇量才是最有用的.
3) TELC/Goethe比较偏学术, 大多是面向学生设计的. 其实在瑞士有面向来瑞工作的外籍人士的更简单实用的考试, 不但考试时间短而且难度相对较低, 比如接下来要介绍的KDE考试--

KDE考试简介

KDE考试是苏黎世州政府对外籍人士推出的德语认证, 难度为 ...

又是很久没更新博客和公众号, 昨天想更新一篇关于瑞士驾照的内容, 写作本身其实挺流畅, 但是在发布到博客和微信公众号的过程中费了不少时间和功夫...

其实我过去一年多在私人笔记(zim/obsidian/foam)里写了不少内容, 但是都没有发布. 一部分原因也是这些发布过程中的阻力(friction)造成的, 尤其是很长时间不碰又会忘记, 需要重新摸索着发布.

这里记录一下我目前文章的写作和发布流程(包括每一步的预估耗时), 反思一下哪些环节可以优化(甚至自动化).

I-文章写作

博客写作主要在zimwiki编辑器里进行. 十年过去了, 现在虽然也开始用obsidian和foam, 我感觉zim依然是专注编辑内容的最佳工具, 编辑体验非常流畅.

(关于这些笔记软件以后有机会再聊).

II-发布到个人github博客

  1. 把zim里的文章导出为markdown : 5~10min
  2. zimwiki导出markdown文章源码 — zim里右键菜单
  3. VSCode打开博客目录, 新建一个markdown文件并粘贴内容
    • 我用pelican生成静态博客, 需要在markdown开头加上一些metadata(标题/标签/日期等)
    • 用VSCode的markdown预览查看和修复排版问题(因为zim的导出不是100%完美)
  4. 纯文字的内容还好, 如果附带了图片, 还需要手动在images/<slug>/新建文件夹, 把zim里的图片放进去 ...

去年四月份我提交了国内驾照换瑞士驾照的申请, 经历了将近一年时间, 考挂了三次才终于在今年三月拿到了瑞士驾照... 计划写几篇文章记录一下我学车和考驾照的过程, 把遇到的坑和各种注意事项列一下, 希望能帮助到更多人.

如果你已经是个老司机, 只要通过了瑞士的换驾照考试, 立马就可以拿到瑞士驾照了. 本篇就介绍申请国内驾照换成瑞士驾照的流程.

苏黎世交管局("Strassenverkehrsamt", 简称stva)官网上有一个介绍外国驾照转换的页面, 一切信息以官方网页为准.

1-打印&填写表格

关于外国驾照在瑞士开车:

  • 欧盟或者日本驾照: 可以直接在瑞士开车
    • 交管局官网上有一个pdf文件 列出了所有不需要考试的国家/地区
  • 国内驾照:
    • 在来瑞士的第一年, 可以用原先的驾照(加翻译件)在瑞士开车
    • 超过一年以后, 原驾照不再有效, 需要通过换驾照考试

要报名换驾照考试, 首先去官网下载«Gesuch Umtausch eines ausländischen Führerausweises»表格.

https://www.zh.ch/content/dam/zhweb/bilder-dokumente ...

DJI运动相机拍摄的视频体积都比较大, 查了一下因为encoding是H264, 如果改成H265的话压缩率会高很多.

转换的命令是: (ref. stackoverflow)

ffmpeg -i input.mp4 -c:v libx265 -vtag hvc1 output.mp4

加上-qscale 0可以保持quality (不过好像对h265不管用? ref. stackoverflow)

保留metadata

视频的metadata里有拍摄时间之类的内容, 可以用-movflags use_metadata_tags 或者-map_metadata 0将其保存下来 (ref: stackexchange)

要查看一个视频文件的metadata的话:

$ sudo apt-get install mediainfo
$ mediainfo foo.mp4 > info.txt

例子:

$ time ffmpeg -i input ...

Flutter(或者更宽泛的app开发)可以一句话总结为:

UI = f(state)

即app的当前界面(UI)反映了当前程序状态(state). Flutter的状态管理就是app根据当前app的state的显示和更新UI.

我们假设state是一个类型为T的object, 在下文的购物车例子中, state是当前购物车的内容(类型T=List<Item>).

关于如何在widget tree里获取state, 可以有provider/riverpod等选项, e.g.Provider<T>. 但是如果直接用T作为状态会有问题: 就是当state的值被修改以后, 对应的UI并不会自动rebuild(除非其他逻辑如setState触发了rebuild).

如果希望在state修改以后, UI自动触发监听它的UI更新, 则需要用各种Notifier来包裹state. 例如我们不用T作为state, 而是用ValueNotifier<T>.

这里主要介绍和比较三种常用的Notifier: ChangeNotifier ...

我的旧护照还有几个月过期, 这周在苏黎世中国总领馆更新了护照, 记录一下办理流程 -- 其实还是挺简单的, 而且速度很快.

官网链接和信息

中国驻瑞士大使馆网站: http://ch.china-embassy.org/chn/
苏黎世领事馆网站: http://zurich.china-consulate.org/chn/

(吐槽: 这个俩网站的页面感觉都有点过时了, 还不支持https:)

护照和旅行证办理须知: http://zurich.china-consulate.org/chn/lsfw/hzlxz/t1204294.htm
==> 这个网页是各种护照和旅行证相关的手续的官方信息源, 列出了各种手续的流程和所需材料. (可是它上面没有标注"更新日期", 我第一次看还以为这是几年前的内容.)

苏黎世总领馆联系方式和地址:

【对外办公时间】每周二、周五9:00至12:00
【电话咨询时间】星期四、星期五,14:30-16:00;星期一,14 ...

写公众号最好的时机是五年前, 其次是现在.

==> 所以我俩月前注册了个微信公众号🐱:

而拖延两个月以后, 这周末体验了撰写和发布公众号的流程, 感觉还是和通过github发布blog有点区别的, 这里记录一下.

将markdown转换为公众号文章

微信公众号的编辑界面类似word, 我从markdown导过去的话需要借用第三方工具. 其实这种工具还挺多的, 我找到了三个:

我最推荐的是最后一个网站"mdnice", 和另外两个相比有不少优点:

  1. 支持各种排版主题
  2. 登录帐号以后可以保存多个最近编辑的文件 -- 虽说理论上只要直接复制粘贴markdown就好, 但是说不定就要针对公众号进行调整, 所以能保存一个针对公众号的
  3. 支持把外链转换为脚注(见下文)
  4. 支持不少代码块主题
  5. 代码块太长时可以横向滚动
  6. 还支持Mac风格的代码块, 看上去很高级:

嵌入视频

普通markdown里可以添加youtube或者B站的iframe html代码嵌入视频. 但是微信公众号不支持这个功能.

似乎只支持嵌入腾讯视频上的内容, 或者把视频手动上传到素材中然后嵌入.

不支持外链

微信公众号仅支持公众号文章链接,即域名为https://mp ...

看了Resocoder和Robert Brunhage的两个视频, 这篇总结一下其中的内容(我其实还没实践过).

本文主要参考自: - pub package
- Video by Robert Brunhage
- Tutorial by Resocoder

The problem

Flutter hooks想解决的问题是StatefulWidget的一些常见pattern太复杂, 减少了代码的可读性("readability").

一个典型例子就是animation controller:

class MyPage extends StatefulWidget{
  @override
  _MyPageState createState() => _MyPageState();
}

class _MyPageState extends State<MyPage>
    with SingleTickerProviderStateMixin {
  AnimationController _animController;

  @override
  void initState() {
    super.initState();
    _animController = AnimationController(
      vsync: this ...

这篇文章主要总结了FlutterEngage里的这个talk:

(这个talk的名字的中文翻译挺牛的: "小事一桩:成为开发和设计俱佳的神级人物")

talk里代码地址在: https://github.com/filiph/little_things

这个talk还是挺有意思的, 介绍了如何提升App的设计细节从而获得更高的 "Perceived value": 有时候app本身的功能性和技术性是一方面, 但是呈现给用户的感觉却有可能因为一点点细节而完全不同. 这一点我之前不太重视, 细想一下确实有道理.

1. White space

多使用padding添加空隙和留白, 体现一种高级感~ 结合Flutter的hot reload可以快的实验 找到合适的padding.

2. Typography

换个好看的字体也可以让应用看起来非常高级.

GoogleFont配合hot reload来选择好的字体

3. Color

给app添加特别的配色.

可以从网上找一些配色方案(color palette), 比如:

  • https://coolors.co/palettes/trending
  • https://undesign.learn.uno/colors/

把选好的ColorPalette放在MaterialApp ...