logo
Published on

《自学是门手艺》 读书笔记(1)

说在前面

一次偶然的机会(逛微博)让我看到了这个 repo ,感觉挺有意思的,毕竟我也刚踏上自学之旅没多久,看看有什么先进的经验思想可以汲取。

前言

一切与自学相关的技巧都是老生常谈。

毕业以来,越发发现自学能力的重要性。特别是在临毕业的时候,在一家公司的校招培训期间,某总的一席话也给了我很大的影响,只记得两个关键词“自变量”和“因变量”,每个人在社会中的所占的作用域和值域都取决于个人。所以,比起多愁善感,自怨自艾,不如发奋图强,一心向前。

如何证明你真的读过这本书?

那我就以此文作记录吧。

第一部分

为什么一定要掌握自学能力?

没有自学能力的人没有未来。

的确,从自我驱动的开始逐渐深入学习前端和 Python 以来,越是学习,越是发现自己的不足。当然主要还是本科的时候基础太差,有些东西终究是要还的。

社会发展越来越快,你要面对的人生越来越长,在那一段与你的直觉猜想并不相同的漫漫人生路上,你居然没有磨练过自学能力,竟然只能眼睁睁地看着自己被甩下且无能为力,难道接下来要在那么长的时间里“苦中作乐”吗?

很庆幸,在我毕业之后,我终于 get 了这项技能,目前还在不断挖坑填坑之中。

不过,以我的观察,无论是什么,哪怕只是学会一点点,都比不会强。哪怕只是中等水平,就足够应付生活、工作、养家糊口的需求。

技多不压身,兴趣爱好广泛我倒是做到了,不过现目前拿不出一个精通的,确实很尴尬,多希望将来能在简历上写上一个“精通”呢!

为什么把编程当作自学的入口?

许多年前,不识字,被称为文盲……

后来,人们反应过来了,不识英文,也是文盲,因为科学文献的主导语言是英文,读不懂英文,什么都吃不上热乎的;等菜好不容易端上来了吧,早就凉了不说,味道都常常会变……

再后来,不懂基本计算机操作技能的,也算是文盲,因为他们无论做什么事情,效率都太低下了,明明可以用快捷键一下子完成的事情,却非要手动大量重复……

到了最近,不懂数据分析的,也开始算作文盲了。许多年前人们惊呼信息时代来了的时候,其实暂时体会不到什么太多的不同。然而,许多年过去,互联网上的格式化数据越来越多,不仅如此,实时产出的格式化数据也越来越多,于是,数据分析不仅成了必备的能力,而且早就开始直接影响一个人的薪资水平。

对啊,“文盲”都在进步呢!这么说来,数据分析真的很重要了。

Forward References(过早引用/前置引用)

工作中、生活里,充满了各式各样的“过早引用”。

学编程中最重要的活动就是“阅读官方文档”。学 Python 更是如此。Python 有很多非常优秀的地方,其中一个令人无法忽视的优点就是它的文档完善程度极好。

以后不能再看到英文文档就畏惧了,虽然阅读没什么大问题,就是效率太低了。

《人人都能用英语》

那看完这个再学习一下,英语想想从六年级开始,都学了快十年了吧,还是停留在一个勉强能“看”的水平。

自学者最大的感受就是万物相通。他们经常说的话有这么一句:“…… 到最后,都是一样的呢。”

的确,重要的是思想。拿编程来说的话,其实懂了数据结构和算法,语言都是次要。然而,我数据结构和算法都很菜,又是一个缺点……

在这个领域里,自学的人最多……

跟上大部队。

只靠阅读习得新技能

自己生活工作学习上遇到的所有疑问,书本里应该都有答案 —— 起码有所参考。

“不是什么东西都可以从书本里学到的……”这话听起来那么有道理,只不过是因为自己读书不够多、不够对而已。

又开新坑了,英语真的很重要,至少在当下而言。

  • 中国人写的英文书
    • 张纯如
    • 郑念的 Life and Death in Shanghai
  • 老外写的关于中国的书
    • 费正清的剑桥中国史(The Cambridge History of China)

英语在科学研究领域早已成为“主导语言”(Dominant Language)也是不争的事实。

民国时代的作者连阔如先生写的《江湖丛谈》,粗略扫过你就知道了,江湖那点事儿,也早就有人给你里里外外翻了个遍…… 只不过这书不太容易买到就是了。

这就让人感兴趣了呢!

所以,只要你有一次“只靠阅读习得一项新技能”的经验,你就变成另外一个人了。你会不由自主、哪怕下意识里都会去运用你新习得的能力…… 从这个角度看,自学很上瘾!能上瘾,却不仅无害,还好处无穷,这样的好事,恐怕也就这一个了罢。

这个说法可以的,自从毕业之后通过阅读习得一些能力之后就是一直阅读一直爽啊,只是现在的困境就是读英文文档效率太低了。

开始阅读前的一些准备

别怕,无论说给自己,还是讲给别人,都是一样的,它可能是人生中最重要的鼓励词。

E.编程入门

入口

乔治·布尔

在大学任职期间,乔治·布尔写了两本教科书,一本讲微分方程,另外一本讲差分方程,而前者, A TREATISE ON DIFFERENTIAL EQUATIONS ,直到今天,依然难以超越。

有本书可以闲暇时间翻翻,The Logician and the Engineer: How George Boole and Claude Shannon Created the Information Age。可以说,没有乔治·布尔的布尔代数,没有克劳德·香农的逻辑电路,就没有后来的计算机,就没有后来的互联网,就没有今天的信息时代 —— 世界将会怎样?

数学可真有意思!

布尔运算

计算器和计算机都是电子设备,但,计算机更为强大的原因,用通俗的说法就是它“可编程”(Programable) —— 而所谓可编程的核心就是布尔运算及其相应的流程控制(Control Flow);没有布尔运算能力就没有办法做流程控制;没有流程控制就只能“按顺序执行”,那就显得“很不智能”……

流程控制
for n in range(2, 100): #range(2,100)表示含左侧2,不含右侧100,是不是第三次看到这个说法了?
    if n == 2:
        print(n)
        continue
    for i in range(2, n):
        if (n % i) == 0:
            break
    else:                  # 这里目前你可能看不懂…… 但,先关注结果吧。
        print(n)

尴尬了,后边的 else 我也没看懂,啊啊啊! 问人之后才知道 for 循环正常退出会进入 else , 2333。

for n in range(2, 100):
    if n == 2:
        print(n)
        continue
    for i in range(2, int(n ** 0.5) + 1): #为什么要 +1 以后再说…… n 的 1/2 次方,相当于根号 n。
        if (n % i) == 0:
            break
    else:
        print(n)

优化也没搞懂(为什么除到 √n 后一个数就行了),应该涉及到一个神奇的数学算法了。

值及其相应的运算

针对数字进行计算的操作符有加减乘除商余幂:+、-、*、/、//、%、**。

流程控制

迭代有序数据类型,用 for ... in ... ,如果需要处理没有 break 发生的情况,用 for ... else ...

函数

当我们想把变量或者表达式的值插入字符串中的时候,可以用 f-string:

name = 'Ann'
age = '22'
print(f'{name} is {age} years old.')

但,这并不是 print() 这个函数的功能,这实际上是 f-string 的功能,f-string 中用花括号 扩起来的部分是表达式,最终转换成字符串的时候,那些表达式的值(而不是变量或者表达式本身)会被插入相应的位置……

也是学习了 none-bot 才知道这种方式,确实方便了许多。

print() 的官方文档说明

很多人只看各种教材、教程,却从来不去翻阅官方文档 —— 到最后非常吃亏。只不过是多花一点点的功夫而已,看过之后,就会知道:原来 print() 这个函数是可以往文件里写数据的,只要指定 file 这个参数为一个已经打开的文件对象就可以了(真的有很多人完全不知道)……

不幸的是,我就是很多人中的一个。

“看说明书” 就是这样,全都看了,真不一定全部看懂,但,看总是比不看强,因为总是有能看懂的部分……

的确,有所收获才是更重要的。

还有就是这个 sep=' ', (拷贝出来的)在官方文档的页面上真没看出来有空格,真是有趣。

字符串

因此,在计算机上,浮点数字的精度总有极限。有兴趣进一步可以看看关于 decimal 模块的文档

把单个字符转换成码值的函数是 ord(),它只接收单个字符,否则会报错;它返回该字母的 unicode 编码。与 ord() 相对的函数是 chr(),它接收且只接收一个整数作为参数,而后返回相应的字符。ord() 接收多个字符的话会报错。

由数字构成的字符串,可以被转换成数值,转换整数用 int() ,转换浮点数字用 float()。

与之相对,用 str(),可以将数值转换成字符串类型。

注意,int() 在接收字符串为参数的时候,只能做整数转换。

input() 这个内建函数的功能是接收用户的键盘输入,而后将其作为字符串返回。

由于历史原因,Linux/Mac/Windows 操作系统中,换行符号的使用各不相同。Unix 类操作系统(包括现在的 MacOS),用的是 \n;Windows 用的是 \r\n,早期苹果公司的 Macintosh 用的是 \r(参见 Wikipedia: Newline)。

所以,一个字符串,有两种形式,raw 和 presentation,在后者中,\t 被转换成制表符,\n 被转换成换行。

在写程序的过程中,我们在代码中写的是 raw,而例如当我们调用 print() 将字符串输出到屏幕上时,是 presentation

正如本节开篇所说:

在任何一本编程书籍之中,关于字符串的内容总是很长 —— 就好像每本英语语法书中,关于动词的内容总是占全部内容的至少三分之二。这也没什么办法,因为处理字符串是计算机程序中最普遍的需求 —— 因为程序的主要功能就是完成人机交互,人们所用的就是字符串而不是二进制数字。

看完了才发现 Python 对于字符串已经有了很多很有用的内建方法了,之前还自己折腾写了些格式化和排版的方法,现在看来,这也太逗了,而且还写得很烂……

看完这一节,又深刻体会到官方文档重要性!

数据容器

列表(List)

List Comprehension

Comprehend 这个词的意思除了 “理解” 之外,还有另外一个意思,就是 “包括、囊括” —— 这样的话,你就大概能理解这种做法为什么被称作 List Comprehension 了。中文翻译中,怎么翻译的都有,“列表生成器”、“列表生成式” 等等,都挺好。但是,被翻译成 “列表解析器”,就不太好了,给人的感觉是操作反了……

元组(Tuple)

元组是不可变序列,所以,你没办法从里面删除元素。

但是,你可以在末尾追加元素。所以,严格意义上,对元组来讲,“不可变” 的意思是说,“当前已有部分不可变”……

集合(Set)

事实上,每种数据结构(Data Structures —— 在这一章里,我们一直用的概念是 “容器”,其实是指同一事物的两种称呼)都有自己的应用场景。

Set 当然也可以进行 Comprehension:

a = "abcabcdeabcdbcdef"
b = {x for x in a if x not in 'abc'}
b

注意,并集、交集、差集的方法,可以接收多个集合作为参数 (*other),但对称差集方法只接收一个参数 (other)。

对于集合,推荐更多使用方法而不是操作符的主要原因是:更易读 —— 对人来说,因为有意义、有用处的代码终将需要人去维护。

冻结集合
字典(Dictionary)

有趣,重新学习一遍基础才理解了什么叫做温故而知新,虽然之前看的廖雪峰的教程,果然是师父领进门,修行靠个人了。虽然想着深耕前端,甚至想把现在的 QQ 机器人用 JS 实现,但是感觉 Python 也很不错啊,还是两手抓吧,哈哈哈。

文件

words_alpha.txt

def sum_of_word(word):
    sum = 0
    for char in word:
        sum += ord(char) - 96
    return sum

with open('results.txt', 'w') as result:
    with open('words_alpha.txt', 'r') as file:
        for word in file.readlines():
            if sum_of_word(word.strip()) == 100:
                result.write(word)

如何从容应对含有过多 “过早引用” 的知识?

  • 过早引用就是无所不在
  • 不懂也要硬着头皮读完
  • 磨练 “只字不差” 的能力
  • 好的记忆力很重要
  • 尽快开始整理归纳总结

人家随手做个图,都舍不得不精致:

Iterables vs. Iterators vs. Generators

  • 先关注使用再研究原理
  • 尊重前人的总结和建议

Python 中有一个概念叫 PEP,Python Enhancement Proposals,必须找时间阅读,反复阅读,牢记于心:

https://www.python.org/dev/peps/pep-0008/

到最后,你会体会到,这不只是编程的事,这种东西背后的思考与体量,对整个人生都有巨大帮助。

官方教程:The Python Tutorial

The Python Tutorial

Python 社区为了建设完善的文档,甚至有专门的文档制作工具 —— 得益于 Python 社区从一开始就非常重视文档规范 —— Sphinx。你在网络上最经常看到的计算机类文档,很可能都在这个网站上:Read the Docs

请牢记且遵守这个原则:

第一查询对象只能是官方文档。