多列数据的分类统计

这个问题在三两年前就2022年4月,2022年11月分别困扰过我。当时解决了,然后忘到脑后。后来又遇到同一次问题,虽然后来也解决了,然而解决之前又一次走上同一条弯路,这感觉令人不悦。

最近2023年7月,又一次遇到同一类型的问题。探索的顺序和以前又完全相同。我不禁想起我的本科导师李树杰老师教导过我的,“杨儿啊,你得做笔记啊。”我当时说什么来着,“那些失败的过程有啥好记的。”

得正经记录一下了,不然还会第四次错。贴出来是最好的记录,因此有了这个帖子。

先从问题的背景和故障现象说起。

微信图片_20230722224008

1. 问题

如下表所示,是学生对教师授课效果的评价。例如,阿大同学认为,教师第一章讲得优,第二章讲得良,第三章讲得中。依此类推。

要求是,统计 每一章 分别 有多少优、多少良、多少中、多少差。即,想得到下面的表格。

按上表所示,我们可以看出,纵向看例如第一章;有7人优,2人良,1人中,共10人;横向看例如优的人数,第一章7,第二章4,第三章2,共13人。

另一个类似问题的场景,订餐-派送。如下表所示,我们希望按宿舍得到一张表,按宿舍-楼层再得到一张表。每张表都按 早餐每种菜品多少份、午餐每种菜品多少份、晚餐每种菜品多少份 计数。

需求/字段尚不稳定,可能多次随时变更。每次变更后都要求 快!

2. 为什么用透视表不行

统计数据最快的不是R或者python,更不是matlab。而是excel。这里的快不是指执行速度,而是指开发。响应快速,培训周期短,用户接受迅速,部署环境简单(经常已经安装过)。

Excel里看起来最像解决方案的是功能强大的 透视表。

然而不行。

关于透视表的使用,值得另用一篇博客才能说清楚。在此暂且略过,假设你已经会了。我尝试了每个字段在行或者在行,尝试了各种计数值的方法,都得不到我想要的结果。各种尝试的结果都非常乱,在此不贴图了。

我想要的结果是,再贴一遍,如下。

中间是计数值;行,是优良中差;列是……每列分别统计。

如果每列分别统计,但是不要求放在一张表中,透视表是可以胜任的。如下。

我们可以看出,这三张表合在一起,就是我希望的结果。

严格地说,这三张表(每张表取1列,横向拼接在一起;
并且行标签都使用 优、良、中、差这4个条件;
并且计数值都使用 优、良、中、差这4种情况对应的计数)合在一起,就是我希望的结果。

“合在一起”符合这么复杂的定义才行。但是透视表的 多列 并不是这个意思。

透视表的 多列,是指 每一列作为一个条件,这些条件以 与操作 复合。例如

以上数据得表下表。

使用透视表的前提条件是 只有1列是数据(计数项,或者求得项等),基余的列都是条件。而我在这里遇到的两张表,学生评教师的 和 订餐-派送 的,其中的 每章 或者 每餐,都不是条件,而是多列数据。

如果从SQL的角度考虑,那么相当于 group by 语法。Group by后面如果有多个列/字段,列/字段之间用逗号分隔,其含义是 既符合又符合,例如 既是东北地区,又是吉林,可爱度10;东北地区所有省份可爱度之和 30。

另一个可供参照的技术是 平行数组。两个数组是独立的,一个数组是语文成绩,另一个数组是数学成绩。两个数组都使用学号作为下标,因此发生关联。两个数组都是计数或求和项,下标(对应excel中的左侧那些列)是条件。

3. 解决方案0 归约

有个近乎耍赖的方案。这个故事告诉我们:1.很多巧妙的方案都近乎耍赖,然而有效;2.巧妙不得长久和通用。

既然我们要求的是计数,那么如果正确赋值,我们可以只计数,而不分类、统计、汇总。因此也不需要透视表。

这个问题,我们把 优、良、中、差分别赋值为10、8、6、4。在这里,我们假装这就是教务部门要求的赋值权重,或者教师不会得到比4分还低的评价。事实上的要求共5档,然而4档还是5档并不影响我们的技术讨论,因此忽略这一区别。Ctrl-h,给出对应赋值,全部替换。

得到下表。

求平均值。

得到下面的表格。

可以看到,第一章教学效果最后,第二章稍差,第三章快放弃了。

虽然以上数据已经符合教务部门的期待了,但是在以上归约过程中,我们舍弃了优、良、中、差每个档次的数量,因此丢失了一些细节。

在 订餐-派送 问题中,按类别计数这一节细不能丢弃,如何赋值呢?

令几种类别 正交,使用多项式。用每“位”数字对一种类别计数。

特色1 1
特色2 10
特色3 100
基本 1000
全素 10000

得到下面的表格,计数。

早餐这一列3205的意思是 3份基本,2份特色3,0份特色2,5份特色1。按宿舍和楼层求和,可以得到 地点-类别 派送数量。

春华,2份基本,3份特色1。

如果计数超过10种,那么可以使用为每种类别预留多位数字。

4. 解决方案1 按列分别统计后合并

还可以把多列数据拆开,对每列数据单独统计。

4.1 透视表

对每一章分别用透视表统计。

手动排序,得到下表。

把行和列改为第二章。

得到第二章的统计结果。

用同样方法得到第三章的统计结果。把三章数据横向拼接,得到下面的表格。

4.2 Access - group by

把Excel粘贴或导入到Access。

新建查询,SQL视图如下。

执行得到结果,尚未根据优良中差排序。

然后对F2排序,横向合并,略。

之所以使用Access,是因为拆分单列和合并结果比Excel更方便。

4.3 Excel - countif函数

这种方法学自 OLIVER_QIN cnblogs 奔跑的金鱼。

https://www.cnblogs.com/OliverQin/p/9436814.html

在下图中绿色的单元格中使用函数 countif。第一个参数是用于统计的区域,这里对应第一章。第二个参数是判断的依据,左侧的优良中差是手动键入的。“良”是红色,因为当前统计的是良的数量,引用“良”。

注意需要用形如$B$2的绝对引用,这样在向其他单元格复制时引用的位置不会变动。类似的,第二章和第三章如下图。

5. 解决方案2 转变为一维数据-透视表

把列标题作为变量名,改为一维数据。具体操作步骤如下。

第一步,把表格复制三份,纵向排列。如下表所示。

第二步,删除除了第一个以外的标题行。

第三步,增加一列,章节。按下图填写 第一章、第二章、第三章。

第四步,删除并非本章的成绩。

第四步,把第一章、第二章、第三章3列合并为一列。

以上,完成了把列标题作为变量名,改为一维数据。这样就符合透视表的要求,只有一列,即最右一列 作为数据的计数项,其余的左边两列都是条件。

对上面“一维”表格使用透视表。

手动对行和列排序,得到下面的表格。

6. 解决方案3 透视表-多重计算合并计算数据区域

以下方案最为优雅来自,OLIVER_QIN cnblogs 奔跑的金鱼

https://www.cnblogs.com/OliverQin/p/9436814.html

快捷键Alt + D P,调出 数据透视表和数据透视图向导,选择点选按钮 多重合并计算数据区域。

共3步,所以第2步拆成了2a和2b!此处有手动狗头表情。

选定区域,然后点击 添加 按钮。

注意,此时得到的透视表不是我们想要的,如下表。

当前的行、列、值是这样的。

修改为下图所示,关键点是行由“行”改为“值”,即由按行(姓名)改为按值(优、良、中、差)分类。

多列数据的分类统计

这个问题在三两年前就2022年4月,2022年11月分别困扰过我。当时解决了,然后忘到脑后。后来又遇到同一次问题,虽然后来也解决了,然而解决之前又一次走上同一条弯路,这感觉令人不悦。

最近2023年7月,又一次遇到同一类型的问题。探索的顺序和以前又完全相同。我不禁想起我的本科导师李树杰老师教导过我的,“杨儿啊,你得做笔记啊。”我当时说什么来着,“那些失败的过程有啥好记的。”

得正经记录一下了,不然还会第四次错。贴出来是最好的记录,因此有了这个帖子。

先从问题的背景和故障现象说起。

问题

如下表所示,是学生对教师授课效果的评价。例如,阿大同学认为,教师第一章讲得优,第二章讲得良,第三章讲得中。依此类推。

要求是,统计 每一章 分别 有多少优、多少良、多少中、多少差。即,想得到下面的表格。

按上表所示,我们可以看出,纵向看例如第一章;有7人优,2人良,1人中,共10人;横向看例如优的人数,第一章7,第二章4,第三章2,共13人。

另一个类似问题的场景,订餐-派送。如下表所示,我们希望按宿舍得到一张表,按宿舍-楼层再得到一张表。每张表都按 早餐每种菜品多少份、午餐每种菜品多少份、晚餐每种菜品多少份 计数。

需求/字段尚不稳定,可能多次随时变更。每次变更后都要求 快!

为什么用透视表不行

统计数据最快的不是R或者python,更不是matlab。而是excel。这里的快不是指执行速度,而是指开发。响应快速,培训周期短,用户接受迅速,部署环境简单(经常已经安装过)。

Excel里看起来最像解决方案的是功能强大的 透视表。

然而不行。

关于透视表的使用,值得另用一篇博客才能说清楚。在此暂且略过,假设你已经会了。我尝试了每个字段在行或者在行,尝试了各种计数值的方法,都得不到我想要的结果。各种尝试的结果都非常乱,在此不贴图了。

我想要的结果是,再贴一遍,如下。

中间是计数值;行,是优良中差;列是……每列分别统计。

如果每列分别统计,但是不要求放在一张表中,透视表是可以胜任的。如下。

我们可以看出,这三张表合在一起,就是我希望的结果。

严格地说,这三张表(每张表取1列,横向拼接在一起;
并且行标签都使用 优、良、中、差这4个条件;
并且计数值都使用 优、良、中、差这4种情况对应的计数)合在一起,就是我希望的结果。

“合在一起”符合这么复杂的定义才行。但是透视表的 多列 并不是这个意思。

透视表的 多列,是指 每一列作为一个条件,这些条件以 与操作 复合。例如

以上数据得表下表。

使用透视表的前提条件是 只有1列是数据(计数项,或者求得项等),基余的列都是条件。而我在这里遇到的两张表,学生评教师的 和 订餐-派送 的,其中的 每章 或者 每餐,都不是条件,而是多列数据。

如果从SQL的角度考虑,那么相当于 group by 语法。Group by后面如果有多个列/字段,列/字段之间用逗号分隔,其含义是 既符合又符合,例如 既是东北地区,又是吉林,可爱度10;东北地区所有省份可爱度之和 30。

另一个可供参照的技术是 平行数组。两个数组是独立的,一个数组是语文成绩,另一个数组是数学成绩。两个数组都使用学号作为下标,因此发生关联。两个数组都是计数或求和项,下标(对应excel中的左侧那些列)是条件。

解决方案0 归约

有个近乎耍赖的方案。这个故事告诉我们:1.很多巧妙的方案都近乎耍赖,然而有效;2.巧妙不得长久和通用。

既然我们要求的是计数,那么如果正确赋值,我们可以只计数,而不分类、统计、汇总。因此也不需要透视表。

这个问题,我们把 优、良、中、差分别赋值为10、8、6、4。在这里,我们假装这就是教务部门要求的赋值权重,或者教师不会得到比4分还低的评价。事实上的要求共5档,然而4档还是5档并不影响我们的技术讨论,因此忽略这一区别。Ctrl-h,给出对应赋值,全部替换。

得到下表。

求平均值。

得到下面的表格。

可以看到,第一章教学效果最后,第二章稍差,第三章快放弃了。

虽然以上数据已经符合教务部门的期待了,但是在以上归约过程中,我们舍弃了优、良、中、差每个档次的数量,因此丢失了一些细节。

在 订餐-派送 问题中,按类别计数这一节细不能丢弃,如何赋值呢?

令几种类别 正交,使用多项式。用每“位”数字对一种类别计数。

特色1 1
特色2 10
特色3 100
基本 1000
全素 10000

得到下面的表格,计数。

早餐这一列3205的意思是 3份基本,2份特色3,0份特色2,5份特色1。按宿舍和楼层求和,可以得到 地点-类别 派送数量。

春华,2份基本,3份特色1。

如果计数超过10种,那么可以使用为每种类别预留多位数字。

解决方案1按列分别统计后合并

还可以把多列数据拆开,对每列数据单独统计。

4.1 透视表

对每一章分别用透视表统计。

手动排序,得到下表。

把行和列改为第二章。

得到第二章的统计结果。

用同样方法得到第三章的统计结果。把三章数据横向拼接,得到下面的表格。

4.2 Access - group by

把Excel粘贴或导入到Access。

新建查询,SQL视图如下。

执行得到结果,尚未根据优良中差排序。

然后对F2排序,横向合并,略。

之所以使用Access,是因为拆分单列和合并结果比Excel更方便。

4.3 Excel - countif函数

这种方法学自 OLIVER_QIN cnblogs 奔跑的金鱼。

https://www.cnblogs.com/OliverQin/p/9436814.html

在下图中绿色的单元格中使用函数 countif。第一个参数是用于统计的区域,这里对应第一章。第二个参数是判断的依据,左侧的优良中差是手动键入的。“良”是红色,因为当前统计的是良的数量,引用“良”。

注意需要用形如$B$2的绝对引用,这样在向其他单元格复制时引用的位置不会变动。类似的,第二章和第三章如下图。

解决方案2 转变为一维数据-透视表

把列标题作为变量名,改为一维数据。具体操作步骤如下。

第一步,把表格复制三份,纵向排列。如下表所示。

第二步,删除除了第一个以外的标题行。

第三步,增加一列,章节。按下图填写 第一章、第二章、第三章。

第四步,删除并非本章的成绩。

第四步,把第一章、第二章、第三章3列合并为一列。

以上,完成了把列标题作为变量名,改为一维数据。这样就符合透视表的要求,只有一列,即最右一列 作为数据的计数项,其余的左边两列都是条件。

对上面“一维”表格使用透视表。

手动对行和列排序,得到下面的表格。

解决方案3 透视表-多重计算合并计算数据区域

以下方案最为优雅来自,OLIVER_QIN cnblogs 奔跑的金鱼

https://www.cnblogs.com/OliverQin/p/9436814.html

快捷键Alt + D P,调出 数据透视表和数据透视图向导,选择点选按钮 多重合并计算数据区域。

共3步,所以第2步拆成了2a和2b!此处有手动狗头表情。

选定区域,然后点击 添加 按钮。

注意,此时得到的透视表不是我们想要的,如下表。

当前的行、列、值是这样的。

修改为下图所示,关键点是行由“行”改为“值”,即由按行(姓名)改为按值(优、良、中、差)分类。

对行和列手动排序,得到下面的表格。

总结

(1)核心原理 透视表认为只有一列数据是计数项,其余的列都是条件。

所以可以 拆分为单列统计再合并。

所以可以 把通过把标题改为变量名,把多列数据转为一维数据。

(2)特殊技术 数据透视表和数据透视图向导 可以 多重合并计算数据区域。

(3)你得做笔记啊。失败的实验也同样重要。发表是最好的记录。

对行和列手动排序,得到下面的表格。

7. 总结

(1)核心原理 透视表认为只有一列数据是计数项,其余的列都是条件。

所以可以 拆分为单列统计再合并。

所以可以 把通过把标题改为变量名,把多列数据转为一维数据。

(2)特殊技术 数据透视表和数据透视图向导 可以 多重合并计算数据区域。

(3)你得做笔记啊。失败的实验也同样重要。发表是最好的记录。

微信图片_20230722224018

好工具 | 平铺窗口WindowGrid

窗口在屏幕上以什么样的风格布局,我见过几种典型的方案。

一种是层叠的,或者浮动的。就是一般我们所见到的情况。如下图所示,三个窗口互相有覆盖的区域。激活的窗口在最前面,挡住后面的窗口。工作的时候视线在这些窗口间转来转去。

我见过最疯狂的层叠,是在大二的时候,看机房里旁边的师兄玩windows3.1自带的纸牌游戏。一大堆纸牌从远到近,从上到下,倾泻而下,后出现的覆盖先出现的。我以为是他写的程序,问这个是怎么实现的。他说这个可容易了。这么炫的效果又特别容易,我更加觉得自己无知。后来有另外的师兄告诉我,那是纸牌游戏打赢时候的过关效果动画。

我见过其次疯狂的层叠,是实验课的时候看到不少同学的编程界面。那么大个显示器,整个都被按钮、菜单、toolbar、广告、各种无关的窗口占据着,留了不到十行五十来个字符的空间,挤在里面写代码。大概就像下图这样。

这类同学往往倾向于用鼠标编程序,在写代码的过程中用鼠标比键盘还多。

层叠以外的风格,我本人走的是另一个极端。无论编程序还是写文字,绝大多数情况下,我都是把当前窗口设置为全屏。不仅最大化而已,而是要占据整个屏幕,连菜单和按钮都隐藏起来。绝大多数操作用快捷键,鼠标也几乎不动。

看起来就像这样,同一时刻只能看到一个窗口。Word快捷键 alt-v u 全屏,退出全屏按ESC。

在用word写作文字时,经常需要用鼠标翻页,使得我正关注的段落在屏幕的正中间。使用 Emacs 则这个操作可以由键盘 C-l 完成,令当前位置上下居中显示。

像这样。Emacs和Firefox全屏快捷键 F11。

如果不是正在写文字或者写代码,我的窗口口风格也并不总简洁到如此极端,而是采用平铺式 tiling的风格。

平铺式风格,又称为瓦片式。整个屏幕划分成若干区域,每个区域显示一个窗口。窗口之间互相没有覆盖,分别在某个区域里最大化。如下图所示,左侧、右上、右下,分别由三个不同窗口占据,窗口间彼此不覆盖。因此可以同时看到三个窗口,但是工作时如果要打字输出,那么需要切换激活的窗口。

平铺式还有个特性对我有帮助。我视力不好,需要非常靠近显示器。与你不同,你看屏幕左上角,只需要转动眼睛,我需要向前探头,再上,再向左。费时间而且易疲劳。所以,我希望窗口特别是我关注的段落能精准地显示在我希望的地方,这样能减少左右移动脖子。

平铺式的窗口管理器(以及各式窗口管理器)在Linux下非常繁荣。Dwm,awesome,xmonad,sawfish,xfce4,各具特色。Windows操作系统下,我长期用过一个,忘了名字。这一轮装机器时似乎找过,找不到了,也许停止开发了。微软开发的PowerToys中的FancyZones,看介绍也非常不错。但是PowerToys是个全家桶,包括很多我不关心的功能,尺寸也不小。所以我没有使用。

我用了 WindowGrid,感觉不错。在这里 http://windowgrid.net/。安装文件也就是运行文件,553KB。运行时占内存30MB多一点,CPU 0。

操作的过程很方便。鼠标点击窗口的标题栏,不要松开,这是拖动窗口的起始动作。差异是,此时按下空格键,当前窗口变成青色,鼠标拖动,只能在事先分配的几个区域中停靠。这几个区域,就是瓦片。如下图所示,青色细线划分了区域,3*2的青色范围是当前正要停靠的区域。

我的机器设置了12个纵列,1行。经常把窗口停在左起第3列到右数第3列之间,正对着我的眼睛。

12*1,这比windows内置的 左1/2,右1/2,左上、右上、左下、右下多了些选择。特别是windows内置的区域要么偏左,要么偏右,居然没有正中间u我最需要的这种配置。

鼠标左键在窗口标题栏按下时,按下 左control 可以只移动而不改变窗口大小。也只能移动到指定的几个区域中,在目标区域中最大化窗口。

 

如何将无损音频格式FLAC转换为其他格式,如MP3或AAC?

如何将无损音频格式FLAC转换为其他格式,如MP3或AAC?

---------------------------

用ffmpeg。

  1. 测试播放 flac 格式的文件。
ffplay filename.mp3

2. 转换

ffmpeg -i filename.flac filename.mp3
ffmpeg -i filename.flac filename.aac

3. 测试转换结果,播放mp3和aac格式的文件。

4. 慎重起见,换个播放器试试。

用微软windows自带的媒体播放器播放,没有问题。因为界面看起来就是空白的窗口,所以略去截图了。

文件大小如图所示。

由太阳角度和时间求地点

假设有张照片,有太阳照射下的影子,知道房屋墙基的角度,知道照片拍摄的时间。求拍照的地点经纬度。

1. 题目

就是这张照片。

C:\Users\young\AppData\Local\Temp\WeChat Files\365306cb65c4ecd6d88843a2db30b84.jpg

橙色线,即墙基的角度,为东偏北25.4度。

(原本拍照想题目的时候,以为房屋是正南正北的,即墙基是正东正西走向。在百度地图上看了一下,并非如此。截图放在geogabra里量了一下角度,即上图。)

拍摄时间为 2023年6月30日15:22。

2. 分析

2.1 概念

本篇标题中的“太阳的角度”并非单一变量,而是包含两个数据。其中之一是 高度角 Elevation,另一个是 方位角 Azimuth。

高度角,指 在纵剖面上,太阳的投影-观测者-地平线 之间的夹角。

方位角,指 在水平面上,正北-观测者-太阳的投影 之间的夹角。

https://gml.noaa.gov/grad/solcalc/azelzen.gif

上图来自 https://gml.noaa.gov/grad/solcalc/glossary.html#azimuthelevation.

图中,h为高度角,A为方位角。

2.2 原理

太阳的高度角 与 时间、纬度 有函数关系。由高度角、时间求得的纬度不唯一,分别在太阳在地点上的直射点两侧,距离太阳在地点上的直射点有相等的纬度差。

太阳的方位角 与 时间、经度 有函数关系。

例如下面的示例,由经度、时间 求得 太阳的方位角,由纬度、时间求得 太阳的方位角。我们需要的是两个反函数,由 太阳的高度角、时间 求得 经度,由 太阳的方位角、时间 求得 纬度。

https://www.osgeo.cn/app/s1904

我们需要找公式或找到可查的表。

2.3 自变量

函数值是 经度和纬度,我们需要的自变量 为 太阳的高度角、太阳的方位角、时间。

时间已知。

太阳的高度角可以由建筑的影子和建筑的比值得到;太阳的方位角可以由墙基的角度得到正北,由建筑的影子在大地上的旋转角度得到。

影子长度的测量和影子角度的测量,细节在下文中。

3. 测量

在照片上做出辅助线,得到下图。

图中的角β是高度角。

图中的角 α与方位角有关。把百度地图与照片叠置,旋转照片得到下图。

其中绿线为正东正西走向,红线为太阳影子的方位角。因此太阳方位角与东西方向的夹角为
25.4度-∠GFH。

3.1 太阳的高度角

根据带辅助线的照片,用geogabra可测得太阳高度角41.82度。

或者 根据房角高CD的像素个数 与 房角的影子长DE的像素个数,二者比值构成太阳的高度角β的正切。根据反正切可求得β角大小。

用 画图 测量像素的坐标,在excel中用勾股定理算得距离。用反正切求得角度为40.5度。

注意到此处有误差,由于视角并非水平,因此求得的角度略小于真实值。考虑到影子的本体是建筑物而不是较短的钉子,因此测量误差较小;并且视角高度不大,所以认为误差可以接受。

3.2 太阳的方位角

视角高度不大,因此对水平面角度(和长度)的测量误差较大,需要做透视矫正。

选了个容易使用的工具。用华为手机拍照功能中的 智慧视觉(左上角)| 扫描 功能,校正照片。

其中左上角是房角在水平面上的投影。左上角-右上角和左上角-左下角 之间等距,由假设栏杆的每根立柱间隔无论左右方向和前后方向都是相等的推得。右下角是做平行线得到的。

测得太阳影子与房基间夹角23.02度。

因此从正北顺时针的方位角为 270-(25.4-23.02)=267.62度。

4. 代入公式

所需公式在网上可以查到,未重新推导。

4.1 高度角

4.1.1 高度角公式

高度角公式

https://www.zhihu.com/question/51315574

sin hs =sinφ·sinδ+cosφcosδ·cosΩ

其中

hs 为高度角

φ 为地理纬度

δ-赤纬

Ω-时角,deg

4.1.2 赤纬公式

赤纬公式

https://zhuanlan.zhihu.com/p/265303609

https://pic4.zhimg.com/v2-54d355b186fcee176de2edb3fd45c3fb_r.jpg

其中t为由3月21日到所求日期6月30日的差,用excel求得值为101,如下图。

把101代入赤纬公式得到23.15度。旁证检验,6月30日刚过夏至不久,太阳由北回归线23.5度向南,求得赤纬的结果与此符合。

4.1.3 时角

在高度角公式的贴子中,孔sysu

求得15:22对应的时角为 (15.37-12)*15=50.55度。

4.1.4 反函数

不必求反函数,可以根据高度角公式在excel中制表,局部如下。

上图中,由纬度、赤纬、时角三个变量求得高度角。其中赤纬和时角在本题中是固定值,已求出。以1度为间隔穷举所有北纬纬度。

观察表格可以发现,在高度角40度左右对应的纬度范围相当大。如果考虑到测量的误差,北纬10度至北纬60度都有可能。

画XY散点图如下。

散点图由上图可以看出,根据高度角求纬度,由于高度角范围较小,所以计算得到的高度角误差较大。(纬度分辨率相当低。)

4.2 方位角

不需要引入方位角公式。

时差,经度差与时间差对应,每360度对应24小时。因此 360/24=15,即每小时对应15度,或每度0.067小时。

拍照时间使用东八区时间-北京时间。同一时刻,东八区中央经线东经120度的太阳方位角为259.56度。根据 https://gml.noaa.gov/grad/solcalc/azel.html 查得。

此前已算得太阳的方位角267.62度。与东八区间的方位角相差267.62-259.56=8.06度。照片所在地比东经120度的太阳更偏西,所以地点更东,120+8.06=东经128.06度。或者按每度111km,拍照地点为由北京向东8.06*111=894.66km。

5. 验算

剧透得知,照片拍摄地点为 吉林省长春市东北师范大学净月校区。

根据 Stellarium 得到 经纬度。

https://gml.noaa.gov/grad/solcalc/azel.html

查得高度角41度左右,方位角264度左右。

或者 用 https://scienceasdf.github.io/site/solarAngle.html 在PC机获得大致的经纬度。

得到高度角为41度左右,方位角264度左右。

https://www6b3.wolframalpha.com/Calculate/MSP/MSP550511ie5c243908hid200003i4hhge80hh56880?MSPStoreType=image/gif&s=4

似乎看起来不错,由经纬度算得的高度角和方位角 与 测量值相差不大。

测量值 根据经纬度的计算值 误差
高度角 40 41 -1
方位角 268 264 4

然而误差相当大。

因为纬度分辨率差,所以高度角即使测量非常精确,求得纬度的范围也非常大。按我的测量,纬度从北纬10度到北纬60度,跨度5550,大致相当于从漠河到曾母暗沙。

方位角差4度合地面4*111=444km,从长春到珲春,再远一点就是日本海。

 

二猫的童年

二猫中考结束了,兴高采烈地喵喵叫,再也不用上初中了。说,看着满床满地满书桌的资料,就想应该抽出一张来复习。就像在考场上发现题目比平时简单,告诉自己“以后中考的时候可以慢点答”,然后遽然发现,正在中考。童年转瞬即逝,即使我经常还错觉她仍然是不一点儿高的孩子,却早就比二猫妈还要高了。

所以,趁时光不远,正是时候写点什么回顾一下二猫的童年。

一直以来不太写孩子的故事。一方面我觉得需要尊重她本人的意愿,而她在更小的时候恐怕没有能力辨别到底是否赞同公开讨论她的故事。另一方面,大家听别人家孩子的故事,通常怀着“可供借鉴”之类的心态吧。私以为成年以前,判断孩子某些特质或家长选择的利弊还为时过早。即使成年以后,我们就能断定怎么做是对的么?总之,把孩子视为孩子评判,有违我的准则。因此,这一篇并非希望有所检讨或借鉴,而是单纯回忆。

包括幼儿园前,幼儿园、小学、初中。以下是我的回忆,不是二猫本人的回忆。因为二猫在过了某个时间点以后,突然就忘掉了童年时的很多事,像开关卡搭一下。她会说,“对对,你提到过的,但是我一点印象也没有了。”

二猫从小语言能力非常突出。说话早,认字早。当时我们都感觉非常厉害,就是那种——家长自己觉得这孩子太棒了,居然这么牛,然而过了一两年,每个孩子都会拥有同样能力——的那种厉害。二猫没有经历过 饭饭,香香,臭臭 这样叠字的阶段,能说单字以后每多久就可以说简单的句子。

和她聊天的时候与面对成年人的感觉差不多,除了人生经验还不够。比如我提到我小时候菜里肉太少,她问,是因为奶奶觉得吃肉多不健康吗?

幼儿园的时候,在我身后的墙上写很多字。应该说是很多笔画,她认为那是字,而且每个字都有读音。再问一遍还能认出来,或者记起来吧。再大一点,问我某个字怎么写。我瞎写一气骗她。她说,你写得不对。我说,正确的应该怎么写。她说,我不会写,但是我认识。

认识字多,所以在学前就读了很多书。多到什么程度呢?小学二三年级的时候,老师要求大家把最近一年读过的书名写在一张纸上。二猫用特别小的字,写了满满一页。她说,还有,写不下了。老师认为二猫在说谎,说,不可能,一个人不可能读这么多书。我和二猫妈考虑再三,要不要跟老师解释一下,决定还是沉默。这种沉默在小学入学面试的时候,二猫也做过。要求大家读画本,二猫拿起来就念,毫不犹豫。老师问,你是不是读过这本。二猫说,没有。但是她没有提议,你再换一本给我读吧。

某次作文,二猫提到,小的时候妈妈指着书上的字给她读画本,后来有一天就说:你已经是个大孩子,可以自己读了。二猫太喜欢那些故事了,只好自己读。老师感叹,真是聪明的家长。这里有个可笑的潜在负面效果。多数汉字二猫都是自学的,所以读音也是自学的,不少汉字在小学阶段仍然只读半边。聊天的时候出现过好多我们听不懂的词。现在都不记得具体是哪些了,我随便编一个吧。比如她可能说“见贝要求如何如何”,问了半天,写下来,是“规则”。大致如此。讲解完她自己也哈哈乐。二猫妈审稿到此,说“羊圈(quan)”。二猫说,对对对,当时我读的是《吹小号的天鹅》,把羊圈(juan)读成了羊圈(quan)。

再后来某次家长会的时候,老师请二猫妈做了一次报告,讲如何引导孩子读书。二猫妈提到,我们自己没事也喜欢读书,每年也买多少多少钱的。

喜欢读书,有自己的书架,后来又溢出其他架子上,散到地上床上。特别喜欢《夏洛的网》,用里面主角的孩子为自己起了英文名,某种小蜘蛛。喜欢过《玛蒂尔达》,后来很淡然的态度。喜欢《柳林风声》,给我解读过我看不懂的人物动机。我很喜欢《哈尔罗杰历险记》,积极推荐,她说全看过了,有点吓人,没意思。《我亲爱的甜橙树》,看了很多遍,中考结束以后又捧起来了。喜欢三国,因此初中时看了三国志、后汉书、晋书。小时候喜欢看三国,突然有一天说“害怕”。我们猜测再三,因为血腥暴力,因为权谋政治?都不是,就是怕,怕,还想看,还怕看。后来说清楚了,“怕看到关羽死”。当时她还不能区分恐惧和担忧。

比三国更早,在更小的时候,书籍就给了她力量。她非常喜欢看《小猫当当》,当时最喜欢的一本,是关于尿床的。小猫当当尿了床,其他小动物,挨个给出画面,都尿了床。各有特色,大概是小猫当当的是小鱼的形状,熊猫是竹子形状,大致如此,都尿成了自己喜欢的东西。然后大家一起晒被子。结尾是什么,太阳很红?我当时非常奇怪,为什么结尾不是“如果不尿床该有多好啊”。我当时没敢问,任由二猫喜欢这书。直到幼儿园或者小学,我终于有机会提问,为什么喜欢这本书呢,它并不能解决任何问题,甚至没有正面的引导。此时,二猫已经能清晰表达,她说,“看了这本书,我就不害怕尿床了。”醍醐灌顶。

喜欢看书到了痴迷的程度。应该是经常猫起来偷偷看书,因为暑假学校要求看书的时候,她挑了几本必读书目就跑到了床后面。问为什么要躲起来,答习惯了。这种直肠子回答是二猫特色,做法也是一样。因为中午在图书馆读书回班迟到,正被班主任撞到。问去哪了,答图书馆。也许还问了看什么书,肯定答三国演义吧。老师说,图书馆就是你的班级,你去图书馆上课吧。二猫讲这段的时候,我说,孩子,老师是在批评你啊,你可不能像我那样就真回家看动画片去了。二猫说,我回图书馆看了一节课书,特别过瘾。家长再教育,孩子说,老师是认真的,不是在跟我商量,是要求。问,跟图书馆老师怎么说的?答,我老师让我回来看书。图书馆老师后来再见到二猫,问过,你是不是就是老师不让上课让回来看书的那个女生。

喜欢看,也喜欢写。两篇发表在《作文与考试》上。还写了科幻小说《狼蛛》发表在科幻世界少年版上,是信息学竞赛和养昆虫的故事。参加了很多次自然博物馆魏老师组织的活动,抓虫子,养虫子,认虫子。我跟去过一次,学的是《蝴蝶的防御》。她在小说里没有提到——曾经把两只独角仙里大的那个送给了好朋友,还细心附带上昆虫吃的果冻。好朋友把果冻吃了,独角仙饿死了。

语言早熟,在幼儿园时期并不是什么好事。从幼儿园回来,问过得好不好。答,还行。玩什么了?看一会儿云,玩一会儿chuachua(塑料插件玩具,类似乐高),玩一会儿chuachua,看一会儿云。没有多少朋友。她想跟小朋友玩的时候,会礼貌地问“咱们能一起玩儿么?”三四岁的小朋友似乎还不知道她为什么要问。别的小朋友从她手里拿东西的时候,从来不问,抢了就走。有一次在家二猫拿着玩具,我假装在后面追抢,二猫跑两步以后把玩具飞快地扔到前面的地上。我起初很愤怒,怎么能摔东西呢。后来突然想到,有可能,她在幼儿园面临争抢时就只能这样处理。语言有优势,但是体力和斗志上明显不及。并且还意识不到体力的差距。我带二猫在楼下小公园里玩,看到一群比她高,大约到我腰高的孩子,成群地风一样跑来跑去。二猫试图指挥,用语言,你们到这玩,你们往那跑。我乐呵呵地看孩子们没一个答理她。最后一个孩子对我说,叔叔,能把你家孩子带得远一点吗,我们怕撞到她。二猫懵懂地看着我,问,他们为什么不带我玩。我才意识到,还不能充分理解语言和体力的相对性,不只二猫如此,看来是遗传的。

为了锻炼二猫花钱——那个时候手机付款还不普及——大家都用纸质或金属的人民币。为了锻炼二猫,我给她三块钱,让她替我去买可乐,我在门外等她。老板告诉她,小孩儿少喝(也许是不喝,细节我忘了)可乐。二猫说,她不喝,是给爸爸买的。老板说,小孩儿不能骗人。二猫不喝可乐,她试过几次,在不同年龄段,目前的结论都是一致的,难喝。

类似的,还有大人看她戴眼镜,告诉过她,不要看电视。她说,她不看电视。她确实不看,因为家里没有。大人就会说,不看电视你怎么近视了呢?显然不信。她会说,遗传的。大人就会说,近视怎么还能遗传呢。

乳牙很差。大人看到会说,小朋友不要吃糖。二猫说,我不吃糖。大人会说,不吃糖牙怎么会坏呢?二猫的科普几乎没有人信,她说,是遗传的。牙釉质先天发育不全,长出来以前就那样了。

二猫有坚定的意志品质。小时候几乎不吃糖,因为牙齿不好。也不吃巧克力,因为我把大量吃巧克力影响发育的简化版本告诉她了,即吃了不长个。吃水果。曾经对着剩下的唯一樱桃大哭,这是留给爸爸的。那粒樱桃我犹豫再三,吃掉呢,还是奖励给她。记得是吃了,奖励了其他的东西。

说起奖励,有过一次重大奖励。具体奖励的是什么不记得了,但是缘由还记得。小学。……

我们说,知是非,讲义气,必须重大奖励。奖励的内容具体是啥,家长忘了,孩子也忘了。孩子甚至忘了有过奖励。不过,我一直记着当时的感觉,觉得这个孩子很好,很自豪。并非因为这是我的孩子,而是因为我希望我周围的人是这样的人,希望我自己也能这样做。

即使很小的时候,二猫的热情也表现得相当冷静。带出门玩的时候,沉默不语,表情淡定。回家以后跟姥姥白话得没完没了,所见所闻滔滔不绝。也许总有人能感觉到冰下的火焰吧,她在每个学段都有相当铁杆的好朋友。

老猫,是最重要的朋友。二猫妈告诉她,咱们全家其实都是猫,但是这个秘密不要让别人知道。她自认是老猫的媳妇,我和二猫妈的童养媳。老猫的学名是李白,所以后来她狂热地阅读李白的诗和相关信息。

她在幼儿园有个朋友,家里有非常大的院子。我们一起感慨过,有那么大的院子可真好啊。小学的一个好朋友,一起玩过改良的定向越野。就是把果冻吃了饿死独角仙的那位。那位好朋友转学走了,后来在网上还有联系。小学持续到初中的好朋友。小学时我见过,后来初中放学时又见,拖着个大大的行李箱当书包,个子也窜高,认不出来了。运动会的时候给二猫梳头,似乎从受照顾的小妹妹长大成了姐姐。

学校以外的活动,也交到了朋友。马上要中考了,还有微信留言,问地生考试当初如何如何。二猫说,这是合唱团的好朋友。她们在省少年儿童合唱团一起受训和表演,直至二猫上初中超龄退役。后来这位低一级的同学也上了同一个初中,离得不远,但是从来碰到过。也许碰到过,但是大家长变了样子,互相不再认识,但是在网上保持着联系。

说起合唱团,二猫也曾经唱歌跑调来着,但是同一时期却一直保持着绝对音高的听力。在小学的小提琴班老师拉了音符,没有参照,让大家听。她说,是re吧。老师说,大家看一下,这就是听绝对音高。二猫在合唱团练,我在外面走廊里听。和声一起,天籁之音。并不跑调。

除了音乐,也练了舞蹈。中国舞10级,非常容易就拿到了,因为柔韧性非常好。别人哭着喊着压腿压腰,她趴那都睡着了。然而,我们说好了,过了10级就再也不练了,她实在是不喜欢。家长也要言而有信。

与舞蹈相关的,中考体育选了坐姿体前屈,非常容易就可以满分了。不过,参加了辅导班,感觉非常值得。即使容易满分,教练也能给出方案使得更轻松一些,怎么热身,怎么压还是发力,训练时如何利用不对称。跳绳也很容易就满分了,特别是换了好绳;还有教练第一次三两分钟就指出,歪,哪面容易挂住,以及身体前倾这样的技术要领。我们一度担心过的800米,进步也很快,虽然不能满分,也可以高分通过,也许能扣0.3分?不过后来因为疫情后同学们纷纷阳性,中考取消了800米。

钢琴考到央音8级,不好考的那种。视唱练耳老的三级也过了。9级没过,想再练,被我拦住了。我说,孩子,你现在信息学投入这么多时间,钢琴没有足够时间练不可能过去。她说,不过也可以练啊。我说,9级学习挺贵的。她没有再学9级,不过我听起来相当难相当壮丽的曲子已经可以在一周左右练成了。在初中班级的联欢会上表演过。在马上就要中考之前,最后一天在校的时候,跑到大厅弹了一通。中考之前的晚上,在家又弹。这样就很好。

从小学四年级开始,学习以外花时间最长的是信息学,成了非常牛的学姐的小迷妹,认识了很多特别厉害的学长学姐,信息学内外他们都有非常广泛地讨论。未来还会继续学,她仍然保持着狂热,希望作为职业。

小时候的记忆,二猫有些忘得干干净净。几年前我瞎编磁性球的数量不对,她被诈出来说还记得更早的几年前曾经掉到床后一个。这个故事不知道她是否还记得了。不知道她是否还记得,冬天在伊通河回来的路边,厢式车的下面藏着的那个最好的冰溜子。

持续学,一直作为职业的,保持狂热的,是永远也不会忘掉的。即使忘掉的那些,虽然不再是记忆,也已经成为我们的一部分,恒久地影响我们的选择和不断塑造我们。再过很多年,也许我们会忘掉这个特别炎热的夏天。也许会忘掉剧烈变化要么酷热要么暴雨的夏天,在这个夏天中考结束了初中的学业,结束了义务教育阶段。我们也许会忘记如何连接在一起,忘记很多细节,然而我们仍然切实感觉到,正如春风拂面。

微信图片_20230629221117

批量压缩歌曲

有时候听歌。好像停留在了某个阶段不再成长了,所以绝大多数歌曲对我都太新。像刘德华《忘情水》,还有孙燕姿(非AI的那位)《绿光》,老狼《同桌的你》《白衣飘飘的年代》《B小调雨后》,在我听来都是非常新的歌,才听到没多久的感觉。相应的,更新的歌由于基本没听过,就都感觉特别陌生。嗯,就是上古戏曲古董突然听到五四音乐的感觉,有点排斥。所以,当老朋友给我一大批听起来非常熟悉亲切的老歌的时候,我的愉悦可想而知。这旋律,这钢琴或提琴的伴奏,这……原来这首歌的首唱是他/她啊,不如后来谁谁唱得好,怪不得没流行。

过了一段时间,硬盘空间又告罄。删了一段时间各种宝物,今天轮到这些歌了。

2.5G空间可供回收。或者移到移动硬盘,不过那样可能得很久之后才能听了,因为不是顺手就能做的,可能就不做了。删除之前,突然注意到文件扩展名是 .WMA,每个文件10M左右。MP3就可以啊,虽然WMA采样率可能更高,奈何我的音箱以及耳朵没有多么优秀,白白浪费。

压缩一下。

第一步 改名,去空格

为了后续转换能成批操作,我查看了文件名。有的文件名中存在空格,这会要求转换命令中作为文件名的参数必须外加引号括住。需要额外的工作,不如统一把空格去除。

例如:

东北师大校歌 – 老年合唱团版 .wma

改名为

东北师大校歌–老年合唱团版.wma

操作的方法是 用 Total Commander 全选文件,然后 File | Multi-Rename Tool。左上红框中是目标文件,[N]表示原名不增加日期、时间、序号之类。右上红框,Search for中有个 空格,这样就把所有空格替换为 无。

有些同学在描述这一步的时候可能会称为“预处理”——凡是正式行动之前的都是预处理,如果有若干步需要区分,就分别叫 预处理1,预处理2,预处理3。

第二步 遍历文件

Total Commander据我所知不提供 选中以后提交给某个工具处理 这样的功能,还得用 shell 之类的工具,才能指定这200多个文件都需要操作。即 遍历,这些被遍历的文件都执行相同的操作(题外话,在STL和SICP中也有类似思路)。

我隐约记得 linux 下几种 shell 如何遍历文件,但是我的座机 bash shell 下默认不搜索 ffmpeg 这个转换工具。用windows的批处理吧,我语法不熟悉,搜索。

用 bing,关键词:bat 遍历文件。

第一条命中。

写日志,避免以后引用或要查找的时候忘了。

这条指令与我记忆中长得非常像,差不多。(切手指长小段焯水晾干)备用。

第三步 压缩 格式转换

优秀工具ffmpeg有这个功能,语法我记不清了,猜测是

Ffmpeg -i 输入文件.wma 输出文件.mp3

压缩比,比特率,采样率之类的都用默认值。

差不多,(勾芡大火爆炒出锅晾凉)备用。

第四步 技术原型试验

我才不会直接在任何宝物上实施写操作。万一写错了,把宝物写坏了写没了怎么办。打游戏时凡重大事件以前,必save以备load。

在当前目录下随便建个目录,起名 1 (随便起的,一会儿就删除)。把十几首歌曲复制(不是搬移)进去。

在目录1下建个批处理文件,名字是 1.bat(随便起的,一会儿就删除)。1.bat的内容如下。

for %%i in (*) do ( ffmpeg -i %%i %%i.mp3)

命令行下(在Total Commander按ctrl-下键),在目录1下运行1.bat。不到一分钟,mp3文件生成了。播放,效果不错。原有wma仍在。

以上说明技术原型验证通过。

第五步 操作

把所有wma文件复制(不是搬移)到目录1(这是操作台)中。

命令行下,在目录1中执行1.bat。等。

第六步 估算

从下图中可以看出,这首歌典时长将近4分钟,转换速度为50倍速左右。

C:\Users\young\Documents\WeChat Files\wxid_mkn03idldug522\FileStorage\Temp\1686816594230.png

歌典大约250首,需要转换多久呢?

每首转换需要 4分钟*60秒/分钟/50倍速,约4秒左右。

250首*4秒/首,合约16分钟。

已转换得到的mp3每首大小约3~5M,与经验中的每分种1M相符。原WMA文件每首10M左右,这样压缩比约0.3~0.5。

还有十多分钟,正好写博客。

十多分钟后转换结束,时间估算正确。MP3占用文件1M,原WMA约2.5G,压缩比0.4,估算准确。

第七步 清理

不,不叫做 后处理。

把目录1递归删除。

把WMA文件搬移(复制后删除原文件)到移动硬盘,在日志中记录目标硬盘的卷标。

把mp3文件都移到 "music 一人一首成名曲 252首 mp3"目录下。

运动会的回忆

这几天学校运动会,朋友圈和群里热火朝天。看大家集合在雨里走方队,看大家动员和争先恐后报项,持续了一两个星期。决赛之前亮哥在群里借钉鞋。我们叮嘱,岁数不饶人,可别伤到了。他说,预赛的时候别的组都穿钉鞋,被欺负到了,决定一定要欺负回去。

不由得回想起我参加过的运动会。

在所有的运动会里,我大多是作为观众出现的。比你想像得无聊。因为我小学就开始高度近视,而我所在的文化氛围和经济状态都不允许使用望远镜,什么也看不到,就是操场上模糊 一片,所以我从来也没有享受过运动会的快乐。

多数情况下不允许欢呼,除了有指挥的时候。一二三、三二一、一二三四五六七。拉歌,一二三四五六七,我们等得真着急。你可以想像什么也看不清,目标、敌人、友军,什么也看不到,就跟着瞎喊。很久以后我才知道,有些同学可以看到远处有人在跑,甚至能辨认出跑的人是谁。

先是在运动会前排练出上述效果,便装。运动会当天,要穿统一服装。穿过白衬衣黑裤子,穿过黑西服裤子随便。有的是向家长借的,有的是礼服,运动会和祭扫烈士陵园的时候要穿。那应该是最初体会到上级的偶尔灵机一动会带来多大的麻烦。比如小学四五年级,在西册体育场参加全市运动会。参加,我的意思是作为观众。要求戴大檐白帽,就是那种展开特别大个儿,边缘是钢丝,可以非常神奇地拆三折成为直径十多厘米的遮阳帽。特别特别白,比用加了钢笔水洗过的白鞋还亮上几分。模糊有记忆六元或者三十元一顶。之所以对价格如此敏感,是因为在那之前的运动会要求买了小白遮阳帽,就是日本动画片里小朋友常戴的那种。但是之前的小白帽不行,必须买新的。并非垄断,随便去哪里买都行,但是随便哪里都不会更便宜。

我没买,刚好要去修牙还是配眼镜,请假成功了。修牙或者配眼镜结束了,时间还早,我去了西山体育场,还找到了班级。老师让我坐在最后一排,看着我戴着不算数的小白帽子,跟我聊天“真热啊”什么的,突然问“你是不是没有帽子啊?”

除了当观众的礼服,还要准备检阅的制服。前文提到,我几乎总是观众而不是运动员。但是几乎每次运动会我都参加检阅。直到大学我才知道,那个检阅的意思是——作为运动员,在开赛之前向主席台(以及绕场一周向所有观众)展示自己。尽管我不是运动员,也要参加检阅。另外,大学以前我就知道,第一个项目即百米短跑的运动员不参加检阅,因为时间不够检录。所以,应该由全体运动员参加的检阅这一程序,有些运动员没有参加,有些参加的人不是运动员。

小学二三年级的检阅要求必须穿运动服,我们当然没有,所以绝大多数同学穿的是线儿衣。如果你不知道线儿衣是什么,可以想像为某种内衣,长及手腕和脚腕,并且手腕和脚腕有松紧带。后来的检阅要求西装,我们还颇奇怪了一下,运动员不是应该穿运动服么?直到在电视上奥运会我看到装西服的入场式,才知道,原来所有的人都可以有许多套衣服,不止拿破仑的妻子或大林和小林里的贵妇人(坏人)才可以有。

检阅以后就是老实坐在观众席上了,在强调运动的场合一动不动。以便取得精神文明奖,这是我作为观众能为班级做的最大的贡献了吧,如果没有拖后腿的话。

举牌子作为背景拼字的活儿也干过。在某个场景里,我似乎是腾飞的腾字里的某个撇的末端。某他的那些场景我就知道自己是哪个像素了,总之是在哨场响起的时候,举起被规定的颜色的方块。并且听到此起彼伏的“我看看谁又错了”“你哪个班的怎么回事”“这么简单的事也做不对呢”。我从未出错过,但是指挥的呵斥令我战栗。战栗到有同学嘲笑过我。在指挥老师不名批评某位同学没站直的时候,嘲笑我的同学告诉我当时我的手指当时已经开始反卷了。然而被不点名批评的同学仍然持续被呵斥,我的手指就反卷得更厉害。事实上,大部分同学都从未出错过,不然以那么短的训练时间主席就没机会看到我们集体的结晶了。但是我们一起被呵斥,“某个同学!”“我看还有人!”。

除了举牌子,还有打竹板。相当震耳朵,我怀疑分贝数可达100左右,应该会永久影响听力。不过比拍手掌强,至少不夹到手的话不疼。还摇过装满钱的罐子。那是大学生运动会还是长春市什么的运动会,大学的时候要求我们参加的。要求每人准备两个易拉罐,不记得对品牌是否有要求了。喝光(是的,得先花钱买到内有饮料的,然后才能喝光),里面放上十枚钢镚。有同学找不到硬币,装上石子问老师,这行不?当然不行。同寝某同学缺几个硬币(还是易拉罐?总之是某种资源),我赠送给他。后来发现我自己也缺,向他要几枚硬币,他死活不给。坏小子们哈哈笑,我也笑,我说:我就这么举着空罐,不放硬币。既轻了很多,又没有人知道,谁还能去特意听某个具体同学的贡献有几分贝吗。

还是长春市这次运动会,在南岭体育场举行。人山人海,要求不得上厕所。我非常听话,在每个节点都按要求“这是最关键的时候”“最最关键”“最最最关键”“最最最最关键”忍受,直到忍不住了肚子疼得厉害。我挪到后排,被一位校园委的老师截住,“你干什么!”我说我上厕所,快憋不住了。他说“这是最关键的时候,你再忍一会,马上就结束了”。我没说话,也许说了“我忍了这么长时间都没去”,不记得了。只记得我迈进了一步,他及时让开了。我对无穷尽地“再忍一下”“最关键”这种没有边界不知进退地“再加一点要求”真是忍无可忍,所以对谈判中试图在划定的底线以后再前进哪怕一小步的,就结束谈判。

运动会持续一整天,彩排有时还持续几个整天。在日落时分,领导会出现,讲话。初三的彩排,我们走方队晒得头昏眼花,校长来了。他说,“我只讲四句话。”我们哗哗鼓掌。他开始第一句,“第一句,好!”他举着喇叭声音嘹亮,我们又响亮地鼓掌。他接着说,“为什么好呢?”然后接下去开始解释为什么好。很久以后才是第二句以及对第二句的解读。然后是第三句,以及对第三句的解读。然后是第四句,以及对第四句的解读。如果我不这样按部就班地写出来,你怎么能体会我们的无聊和愤怒。“这TM不识数吧”,这是当时窃窃私语地主要评价,我奇怪他没有听到。第四句并不是结束,还有总结。

结束前,我们还会为精神文明奖第几,或者第几个被宣布的,为这些纠结很久。我们二班才是最特殊,最优秀,最应该被承认的。也许是二班吧,从小学到初中到高中,到大学,引用李逵的说话,我真的不记得这许多班级到底都是几班了。不过,我们是最特殊,最优秀,最精神文明的,这点我没有忘记。如果是四班,那么就是四班四班我们最强。如果是十八班,那么换个口号。不得性别歧视,所以不能叫十八罗汉最棒。同样不得性别歧视,所以不能叫十八姑娘一朵花。不得涉及宗教,所以不能叫十八层地狱最怎么样。我们需要在运动会以前很久就开始编这套最适合我们的口诀;准备好各种道具,跟家长要钱买或者借,如果这是一次性的可真是糟糕得很,每次运动会都会再次回顾并得到败家的差评;全程做个乖乖的观众,不准说话不准动。

除了做观众,我还一直是报道组成员,就是那个“三年二班报道组来稿”,经常几个人包揽本班所有稿件。我们在运动会前一天,拿着项目单,像亲眼看到一样,把接下来要用的稿件全写出来。有说的,有写的,有抄稿的。运动会当天,还有送稿的,和临时加写稿件的。

也临时做过运动员。跑过110米栏,就是刘翔那个项目。我前一天学的,能左右脚分别上栏。第一次也是唯一一次听到发令枪。听到身后同跑的那位稀里哗啦的踢着,我一个障碍也没有踢倒。然而,我跑得非常慢,预赛就被淘汰了。差一名?直到将近三十年后,在讨论孩子的体育达标时zhumao和向龙教我,还有tiger他们教我,“你的腿倒腾得太慢了啊。”我才知道,不止应该迈大步。

我还跑过5000千米。因为全班谁也不上,只好我去,为了不扣分。体委和我一起去的,他中途退场了,我更需要跑下去。全程是跑的,没有走的时候,保持了运动员的基本尊严。被倒数第二名扣了一圈,到终点的时候体育老师说“你可算到了”。

后来参加过教工运动会。连长叫我替跑过,充个数。还有个三块砖往前挪的项目,我意外地协调,超过第二名老大一截。后来?后来太快了,大意了,掉了下来,没有成绩。还参加过自行车慢骑。我有辆特别小的自行车,在跑道里原地转圈,能向初发点骑回去。准保慢得第一吧。裁判说,不算,违例。我拿出写着规则的纸件来问,非常想知道违哪条例了。大家都劝我算了吧算了。

算了,我觉得大家说得有道理。我闭了嘴,不再讨论,也不想知道错哪了,以后再没有参加过运动会。

修煤气灶 v2.0

本文v1.0中提到的方法有危险,请不要模仿!

本文v1.0提到用绝缘胶带缠绕点火线,经 柳喵喵 和 笑一个 两位指出,在高温环境下有危险。请不要模仿我的做法。后来我购买了点火线换上,不到10元钱,拆卸旧的和换上新的都不困难。

修煤气灶 v2.0

本文v1.0中提到的方法有危险,请不要模仿!

本文v1.0提到用绝缘胶带缠绕点火线,经 柳喵喵 和 笑一个 两位指出,在高温环境下有危险。请不要模仿我的做法。后来我购买了点火线换上,不到10元钱,拆卸旧的和换上新的都不困难。

V 1.0

一起床,二猫妈说煤气灶的右侧灶孔不会打火了。测试一下,有打火的声音,非常小;煤气正常。左侧灶孔正常是电路的问题,并且说明左右两侧电路是独立的。

在网上查了一下,可能是线路中间有打铁(和地线短路),也可能是高压 (发生?)器坏了。

两个灶孔旁边分别拆下3个螺丝。

图示为 拆掉3个*2组螺丝,拔掉旋钮,就可以打开顶面板了。

C:\Users\young\AppData\Local\Temp\WeChat Files\1d3b228058432537a7e42a5153c9d60.jpg

硬用力,把面板和底层脱开。右侧脱开得晚一些,左半边很容易就打开了。得下定决心,能拆开,暴力一下。拆不开上面板时,还拆下过煤气管的加固螺丝,后来看到与它无关。

图示为 右侧灶口的点火线,原本通过右上方的两个塑料卡扣固定,已经从里面拆出来了。

发现导线与灶口附近的铁柱打火,再仔细检查,导线的绝缘外皮有一处裂了。

图示为 点火线有一段烤黑了,有一处绝缘层裂开。裂开的地方和灶口的铁脚之间打火。

C:\Users\young\AppData\Local\Temp\WeChat Files\ab5ce5b9278c76bf3aadc3ff12f7473.jpg

原理判断,因为提前打铁,所以灶孔处没有电火花点火了。

准备加绝缘层。

测试一下解决方案是否有效。在导线和铁柱之间插圆珠笔。导线和圆珠笔打火。

把导线移到离铁柱远一些的地方,把塑料锁扣也移过去一个。孔有点小,对付把卡扣插进去了。导线缠上绝缘胶带。好了,灶孔可以电火花点燃煤气了,说明解决方案有效。

缠绝缘胶带时的操作空间很小,用了前一段在小视频里学到的方法。把绝缘胶带先缠在一截方便筷子上,用筷子作为胶带的轴,把胶带缠在导线上了。

图示为 在裂口处缠上绝缘胶带。

C:\Users\young\AppData\Local\Temp\WeChat Files\80608545345e442cc87e50be55fd328.jpg

图示为 改动布线,让点火线远离铁脚,减少导线受热。原本导线从右上白色卡扣穿过,再贴近铁脚进入灶孔下方。

C:\Users\young\AppData\Local\Temp\WeChat Files\0bcae62b52a23b83c39e9cee939ab2a.jpg

遗留问题有 1.导线固定比原来松动,如果有晃动或者其他原因导线可能移位,靠近金属的话可能再次提前打铁;2.绝缘胶带的介电常数可能还是不如原装的导线绝缘层,毕竟我们一般认为空气也是绝缘的,但是在绝缘层破裂的地方和灶孔点火处被高压轻松电离击穿了。

此处有个安全隐患,是在V1.0当时没有发现的,即经 柳喵喵 和 笑一个 两位指出,绝缘胶带在用火的环境下不安全。

V 2.0

在淘宝买了新的点火线。笑一个 之前指出过,不贵,10元以下。就选了买家最多的一种,6.5元,包邮。

为了拆下旧的点火线,需要把灶孔从基座上拆下来。下图的这个位置在 V1.0 中令我非常犹豫,看不清楚连接的结构,没想清楚需要拆几个螺丝。

在网上看了个视频,此处也跳过了。不过看 up主 动作轻巧的程度,我怀疑“就那么”就能拿下来。果然。灶孔与灶气管线之间,是没有任何锁死装置的,双方都用螺丝固定在基座上。拆下灶孔以后,如下图所示。

下图,拆下旧的点火线,与新的对比。

上图中,下方的是新点火线,两个螺丝之是夹住煤气灶的钢板,以固定点火的高度。上方的是旧点火线,用弹簧和卡扣固定。

下图,新的点火线安装完毕,灶孔固定回基座上。

C:\Users\young\AppData\Local\Temp\WeChat Files\26211bd86ca2b750a15b3314114fe03.jpg

下图,点火线的另一端与基座上的接口连接,硬插进去,插到我用手拔费劲的程度。下图中红色的是新点火线,左侧的截面方形的白色小盒是左灶孔的旧点火线。

C:\Users\young\AppData\Local\Temp\WeChat Files\57dd21092860959ed866cfd111e5dd5.jpg

下图中三个红箭头所指的是新点火线。顶视图。

后来想想不对,应该令点火线远离煤气管,左侧的现状和右侧的原始状态才是对的。改回大致原始的走线位置,参照左侧的角度远离铁脚。

无标题

再看一眼旧线的结构。

下图展示的是绝缘层裂开和烧黑的部分,与线的其余部分的颜色对比。

C:\Users\young\AppData\Local\Temp\WeChat Files\df8e967bacdffdefe1f6b6a1a53d6e5.jpg

再次感谢 柳喵喵 和 笑一个 两位指正。

V 1.0

一起床,二猫妈说煤气灶的右侧灶孔不会打火了。测试一下,有打火的声音,非常小;煤气正常。左侧灶孔正常是电路的问题,并且说明左右两侧电路是独立的。

在网上查了一下,可能是线路中间有打铁(和地线短路),也可能是高压 (发生?)器坏了。

两个灶孔旁边分别拆下3个螺丝。

图示为 拆掉3个*2组螺丝,拔掉旋钮,就可以打开顶面板了。

C:\Users\young\AppData\Local\Temp\WeChat Files\1d3b228058432537a7e42a5153c9d60.jpg

硬用力,把面板和底层脱开。右侧脱开得晚一些,左半边很容易就打开了。得下定决心,能拆开,暴力一下。拆不开上面板时,还拆下过煤气管的加固螺丝,后来看到与它无关。

图示为 右侧灶口的点火线,原本通过右上方的两个塑料卡扣固定,已经从里面拆出来了。

发现导线与灶口附近的铁柱打火,再仔细检查,导线的绝缘外皮有一处裂了。

图示为 点火线有一段烤黑了,有一处绝缘层裂开。裂开的地方和灶口的铁脚之间打火。

C:\Users\young\AppData\Local\Temp\WeChat Files\ab5ce5b9278c76bf3aadc3ff12f7473.jpg

原理判断,因为提前打铁,所以灶孔处没有电火花点火了。

准备加绝缘层。

测试一下解决方案是否有效。在导线和铁柱之间插圆珠笔。导线和圆珠笔打火。

把导线移到离铁柱远一些的地方,把塑料锁扣也移过去一个。孔有点小,对付把卡扣插进去了。导线缠上绝缘胶带。好了,灶孔可以电火花点燃煤气了,说明解决方案有效。

缠绝缘胶带时的操作空间很小,用了前一段在小视频里学到的方法。把绝缘胶带先缠在一截方便筷子上,用筷子作为胶带的轴,把胶带缠在导线上了。

图示为 在裂口处缠上绝缘胶带。

C:\Users\young\AppData\Local\Temp\WeChat Files\80608545345e442cc87e50be55fd328.jpg

图示为 改动布线,让点火线远离铁脚,减少导线受热。原本导线从右上白色卡扣穿过,再贴近铁脚进入灶孔下方。

C:\Users\young\AppData\Local\Temp\WeChat Files\0bcae62b52a23b83c39e9cee939ab2a.jpg

遗留问题有 1.导线固定比原来松动,如果有晃动或者其他原因导线可能移位,靠近金属的话可能再次提前打铁;2.绝缘胶带的介电常数可能还是不如原装的导线绝缘层,毕竟我们一般认为空气也是绝缘的,但是在绝缘层破裂的地方和灶孔点火处被高压轻松电离击穿了。

此处有个安全隐患,是在V1.0当时没有发现的,即经 柳喵喵 和 笑一个 两位指出,绝缘胶带在用火的环境下不安全。

V 2.0

在淘宝买了新的点火线。笑一个 之前指出过,不贵,10元以下。就选了买家最多的一种,6.5元,包邮。

为了拆下旧的点火线,需要把灶孔从基座上拆下来。下图的这个位置在 V1.0 中令我非常犹豫,看不清楚连接的结构,没想清楚需要拆几个螺丝。

在网上看了个视频,此处也跳过了。不过看 up主 动作轻巧的程度,我怀疑“就那么”就能拿下来。果然。灶孔与灶气管线之间,是没有任何锁死装置的,双方都用螺丝固定在基座上。拆下灶孔以后,如下图所示。

下图,拆下旧的点火线,与新的对比。

上图中,下方的是新点火线,两个螺丝之是夹住煤气灶的钢板,以固定点火的高度。上方的是旧点火线,用弹簧和卡扣固定。

下图,新的点火线安装完毕,灶孔固定回基座上。

C:\Users\young\AppData\Local\Temp\WeChat Files\26211bd86ca2b750a15b3314114fe03.jpg

下图,点火线的另一端与基座上的接口连接,硬插进去,插到我用手拔费劲的程度。下图中红色的是新点火线,左侧的截面方形的白色小盒是左灶孔的旧点火线。

C:\Users\young\AppData\Local\Temp\WeChat Files\57dd21092860959ed866cfd111e5dd5.jpg

下图中三个红箭头所指的是新点火线。顶视图。

后来想想不对,应该令点火线远离煤气管,左侧的现状和右侧的原始状态才是对的。改回大致原始的走线位置,参照左侧的角度远离铁脚。

无标题

再看一眼旧线的结构。

下图展示的是绝缘层裂开和烧黑的部分,与线的其余部分的颜色对比。

C:\Users\young\AppData\Local\Temp\WeChat Files\df8e967bacdffdefe1f6b6a1a53d6e5.jpg

再次感谢 柳喵喵 和 笑一个 两位指正。

修煤气灶 更正中

本文中提到的方法有危险,请不要模仿!
本文提到用绝缘胶带缠绕点火线,经柳喵喵笑一个两位指出,在高温环境下有危险。我正在购买准备更换点火线,完成后回来更正本文。请不要模仿我的做法。

一起床,二猫妈说煤气灶的右侧灶孔不会打火了。测试一下,有打火的声音,非常小;煤气正常。左侧灶孔正常是电路的问题,并且说明左右两侧电路是独立的。

在网上查了一下,可能是线路中间有打铁(和地线短路),也可能是高压 (发生?)器坏了。

两个灶孔旁边分别拆下3个螺丝。

图示为 拆掉3个*2组螺丝,拔掉旋钮,就可以打开顶面板了。

C:\Users\young\AppData\Local\Temp\WeChat Files\1d3b228058432537a7e42a5153c9d60.jpg

硬用力,把面板和底层脱开。右侧脱开得晚一些,左半边很容易就打开了。得下定决心,能拆开,暴力一下。拆不开上面板时,还拆下过煤气管的加固螺丝,后来看到与它无关。

图示为 右侧灶口的点火线,原本通过右上方的两个塑料卡扣固定,已经从里面拆出来了。

发现导线与灶口附近的铁柱打火,再仔细检查,导线的绝缘外皮有一处裂了。

图示为 点火线有一段烤黑了,有一处绝缘层裂开。裂开的地方和灶口的铁脚之间打火。

C:\Users\young\AppData\Local\Temp\WeChat Files\ab5ce5b9278c76bf3aadc3ff12f7473.jpg

原理判断,因为提前打铁,所以灶孔处没有电火花点火了。

准备加绝缘层。

测试一下解决方案是否有效。在导线和铁柱之间插圆珠笔。导线和圆珠笔打火。

把导线移到离铁柱远一些的地方,把塑料锁扣也移过去一个。孔有点小,对付把卡扣插进去了。导线缠上绝缘胶带。好了,灶孔可以电火花点燃煤气了,说明解决方案有效。

缠绝缘胶带时的操作空间很小,用了前一段在小视频里学到的方法。把绝缘胶带先缠在一截方便筷子上,用筷子作为胶带的轴,把胶带缠在导线上了。

图示为 在裂口处缠上绝缘胶带。

C:\Users\young\AppData\Local\Temp\WeChat Files\80608545345e442cc87e50be55fd328.jpg

图示为 改动布线,让点火线远离铁脚,减少导线受热。原本导线从右上白色卡扣穿过,再贴近铁脚进入灶孔下方。

C:\Users\young\AppData\Local\Temp\WeChat Files\0bcae62b52a23b83c39e9cee939ab2a.jpg

遗留问题有 1.导线固定比原来松动,如果有晃动或者其他原因导线可能移位,靠近金属的话可能再次提前打铁;2.绝缘胶带的介电常数可能还是不如原装的导线绝缘层,毕竟我们一般认为空气也是绝缘的,但是在绝缘层破裂的地方和灶孔点火处被高压轻松电离击穿了。

 

GPT AI结对编程初体验

入口

chatGPT火了一段时间,我没试,因为我不想翻墙。因为什么?翻墙违法啊,你不知道?我还在观望之中的时候,GPT-4又来了。火的东西多了,承诺多大令人失望,所以我没有着急。

宝玉xp说:

大家快来测试一下集成GPT-4的编辑器Cursor (cursor.so)

我心想,你们测,我围观。

宝玉xp又说:不需要订阅Copilot,不需要API Key。

我在同学们的群里转发了这条消息

https://m.weibo.cn/status/4880070764400024?wm=3333_2001&from=10D3193010&sourcetype=weixin&jumpfrom=weibocom

老学生位同学试了两下,说:不错哎。

并且给出了“生成unity和手柄交互的代码”的体验说“非常好用!”,还有查资料“about WebRTCaudio/video streming”,看起来不错。

安装 https://www.cursor.so/ 到 sandboxie 中试一试吧。

看示例文件的后缀,支持 python 和 js。看配置和实测,C/C++ 也没问题,还有不少语言。

提要求用 汉语或英语都行。

贪吃蛇,业务逻辑,修改需求

做了个贪吃蛇,JS版本。确实强大,连HTML主体都是GPT写的。Ctrl+K提要求。我的要求主体是:生成一个贪吃蛇游戏,JS版本。

为了增加难度,我在初始的要求增加了细节:用 O 作蛇头,用 X 作为食物,用 + 作蛇身。

我增加要求初始蛇身长度3。

我修改按键,由 上下左右 改为 WASD,又改为 HJKL。

甚至不必指出WASD和HJKL哪个键对应哪个方向,他能猜出来。说明玩过反恐精英,习惯使用VI编辑器。

调试最长的时间花在了我的浏览器有插件拦截HJKL按键,运行的时候按键总是不好使。为了找到问题的原因,我要求按键的时候播放声音,要求蛇每走一步播放声音,代码正确。没声音,Ctrl+L聊天,我问为什么没声,他告诉我非常可能受浏览器权限影响的,还告诉我如何解决。我要求按键时弹出窗口,显示按键的字母。这样,发现了按键没被产生 event,进而想到了插件拦截。远程辅助调试的时候,对现场环境的依赖,确实是个难点。需要人类承担责任的部分,得由人工操作,人工是最大的bug。

后来要求用 NENU 作蛇身,代码看起来对的,但是按键不好使了,这条线索没有继续。

我还试了 flappy bird,要求把 管道pipe 改成 柱子column。正确。

不能写论文

同学和同事都说,让他写论文吧。

C:\Users\young\AppData\Local\Temp\WeChat Files\9c02d5e5f8fce6ef01c9c2ca153e759.png

论文不能写,因为是编程专用的。

专用的,不打算聊别的。

解读代码

Zhumao贴来一段代码,问,这段代码能读懂不。

我问了。

他知道这是手动循环展开,还告诉这种优化方法过时了。

俄罗斯方块,逐步提示

我说 写个俄罗斯方块,控制台版本的。

没写完啊。所以我要求继续。之前也见到过代码明显不完整,我问“后面还有吗”,他就继续。

我要求展开函数。

继续展开下一个函数。

怎么旋转方块呢?可以接受或拒绝。

业务逻辑差不多应该就是这样。不过Dijkstra说了:我困惑,数据结构什么样呢?

他不仅回答问题,还委婉偷摸地纠正我的说法。

我要求写一段 L形方块的初始化,然后指着那段代码问,这段代码放在哪里合适呢。

在之前我改乱过一段代码,也回答过我,某段JS代码要放在某个类的构造函数里。

优化和代码风格

要求写个 sin 函数实现,用拉格朗日展开。

// 用拉格朗日展开求sin函数,JS版本

function lagrangeSin(x, n) {

let sinX = 0;

for (let i = 0; i < n; i++) {

let term = (-1) ** i * x ** (2 * i + 1) / factorial(2 * i + 1);

sinX += term;

}

return sinX;

}

function factorial(n) {

if (n === 0) return 1;

return n * factorial(n - 1);

}

以上是上课常讲的故事的第一个高潮,接下来查表法。

// 用查表法实现sin函数,JS版本,精度为角度制 1度

const sinTable = [];

for (let i = 0; i <= 360; i++) {

sinTable[i] = lagrangeSin((i * Math.PI) / 180, 10);

}

function tableSin(degrees) {

const index = Math.round(degrees) % 360;

return sinTable[index];

}

他用拉格朗日展开填表,不够硬。要求硬编码。

给出的硬编码不够多。

填充sinTable[i]的值,i从0至50。不在运行时使用lagarangeSin求值,hardcode.

他像循循善诱的老师“你就这么整就行,例子是这样的……”,我像不争气的学生“你就告诉我答案吧。”

换个算法,用泰勒级数展开,还是求sin。

大E同学说,这家伙会递归。

好吧,我指着 factorial函数说:用迭代法重写求这个。

再快点,用查表法。

再高深一点,用动态规划,我告诉他要实现的函数原来长什么样。

像不像面试题?

写个 strcat,避免内存泄露,效果尽可能高。

逐步引导,几次修改要求。

// Function to concatenate two strings without memory leaks and with high efficiency

// Returns 0 on success, -1 on failure

// Check if the source string is longer than the allowed limit

// Check if the length of dest is larger than src

体会

有同学说:没希望了,想摆烂。

上图来自网上,是电影《喜剧之王》的截屏。

另一个体会是 语言表达和逻辑越好,优势越强。不用牙齿和爪子以后,石刀石斧需要适应。也许新的时代就要到来了,AI作为生产力的利器,淘汰一部分岗位,同时创造新的生产方式。