├── .gitignore ├── .vs ├── VSWorkspaceState.json ├── slnx.sqlite └── the-craft-of-selfteaching │ └── v16 │ └── .suo ├── 00.cover.ipynb ├── 01.preface.ipynb ├── 02.proof-of-work.ipynb ├── Part.1.A.better.teachyourself.ipynb ├── Part.1.B.why.start.from.learning.coding.ipynb ├── Part.1.C.must.learn.sth.only.by.reading.ipynb ├── Part.1.D.preparation.for.reading.ipynb ├── Part.1.E.1.entrance.ipynb ├── Part.1.E.2.values-and-their-operators.ipynb ├── Part.1.E.3.controlflow.ipynb ├── Part.1.E.4.functions.ipynb ├── Part.1.E.5.strings.ipynb ├── Part.1.E.6.containers.ipynb ├── Part.1.E.7.files.ipynb ├── Part.1.F.deal-with-forward-references.ipynb ├── Part.1.G.The-Python-Tutorial-local.ipynb ├── Part.2.A.clumsy-and-patience.ipynb ├── Part.2.B.deliberate-practicing.ipynb ├── Part.2.C.why-start-from-writing-functions.ipynb ├── Part.2.D.1-args.ipynb ├── Part.2.D.2-aargs.ipynb ├── Part.2.D.3-lambda.ipynb ├── Part.2.D.4-recursion.ipynb ├── Part.2.D.5-docstrings.ipynb ├── Part.2.D.6-modules.ipynb ├── Part.2.D.7-tdd.ipynb ├── Part.2.D.8-main.ipynb ├── Part.2.E.deliberate-thinking.ipynb ├── Part.3.A.conquering-difficulties.ipynb ├── Part.3.B.1.classes-1.ipynb ├── Part.3.B.2.classes-2.ipynb ├── Part.3.B.3.decorator-iterator-generator.ipynb ├── Part.3.B.4.regex.ipynb ├── Part.3.B.5.bnf-ebnf-pebnf.ipynb ├── Part.3.C.breaking-good-and-bad.ipynb ├── Part.3.D.indispensable-illusion.ipynb ├── Part.3.E.to-be-thorough.ipynb ├── Part.3.F.social-selfteaching.ipynb ├── Part.3.G.the-golden-age-and-google.ipynb ├── Part.3.H.prevent-focus-drifting.ipynb ├── Q.good-communication.ipynb ├── R.finale.ipynb ├── README.md ├── S.whats-next.ipynb ├── T-appendix.editor.vscode.ipynb ├── T-appendix.git-introduction.ipynb ├── T-appendix.jupyter-installation-and-setup.ipynb ├── T-appendix.symbols.ipynb ├── from-readers ├── Cat-self-teaching-stories │ └── aftermy14dayscamptrial.md ├── baichangping-self-teachingpython-stories │ ├── 122.png │ ├── 233.png │ ├── 54.png │ ├── 55.png │ └── baichangping-self-teachingpython-stories.md ├── junhong-self-teaching-story.md ├── leask-self-taught-stories.md ├── liujuanjuans-self-taught-stories.md ├── liuyunxin-self-teaching-storise.md ├── lyric-self-teaching-stories.md ├── lyric-self-teaching-stories │ └── the-persistence-of-memory.jpg ├── shuimu0579-self-taught-stories.md ├── sxuya-selfteaching-story.md ├── xiaoqiang-self-teaching-stories.md ├── zhangmmin-selfteaching-camp-story.md └── zhangqis-self-taught-stories.md ├── hdi-china-1870-2015.txt ├── images ├── 2_necker_cubes.png ├── Acorn-Electron.png ├── CC-BY-NC-ND.png ├── Joseph-M-Williams-research-visualized.png ├── Lamarr_patent.png ├── Part.1.A.better.teachyourself_2_0.png ├── Part.1.A.better.teachyourself_4_0.png ├── Part.1.A.better.teachyourself_6_0.png ├── Part.1.E.6.containers_66_0.png ├── Phylogenetic_tree.png ├── Tree-of-Life.gif ├── Unix_Glob_Reference.png ├── a-cartoon.png ├── apple-keyboard.png ├── archimedes-eureka.png ├── arguments-order.png ├── backend.png ├── boolean-operators.png ├── class-variables-scope.png ├── code-review.png ├── continue-break.png ├── controlflow-function.png ├── decompose-x.png ├── decompose-y.png ├── devops.png ├── disclaimer.png ├── doc-class.png ├── doc-divmod.png ├── doc-exec.png ├── doc-max.png ├── doc-pow.png ├── doc-print-def.png ├── doc-print.png ├── download-from-github.png ├── four-cones.png ├── framing-bias.png ├── framing-effect.png ├── frontend.png ├── george-boole-google-doodle-2015.gif ├── george-boole-in-1864.png ├── git-command-relationships.png ├── git-time-machine-cover.png ├── github-commit.png ├── github-confirm-merge.png ├── github-create-pull-request.png ├── github-fork.png ├── github-markdown-style.gif ├── github-merged-pull-request.png ├── github-new-branch.png ├── github-open-pull-request.png ├── github-pull-request.png ├── google-homepage-1998.png ├── google-how-effectively.png ├── google-prototype-1998.png ├── google-stackoverflow.png ├── guitar-tab.gif ├── hedy-lamarr-hero-getty.jpg ├── intro.png ├── iter-relationships.gif ├── jupyter-lab-launcher.png ├── jupyter-lab-terminal.png ├── learning-curve-spiral.gif ├── learning-curve-spiral.png ├── list-concepts.png ├── local-tutorial.png ├── operations@2x.png ├── python-containers-2.png ├── python-containers-final.png ├── python-containers.jpg ├── python-containers.pdf ├── python-containers.png ├── python-leading-space.png ├── recursive-function-call.png ├── redemo.png ├── regex-test.gif ├── regex101.gif ├── rename-macos.png ├── rotating-cube.gif ├── search-generated-by-sphinx.png ├── seflteaching-model.png ├── split.png ├── string-concept-table.png ├── string-concepts.png ├── symbols.png ├── sync-fork-1.png ├── sync-fork-2.png ├── sync-fork-3.png ├── sync-fork-4.png ├── sync-fork-5.png ├── sync-fork-6.png ├── sync-fork-7.png ├── three-cones.png ├── vscode-extensions.png ├── vscode-select-python-version1.png ├── vscode-select-python-version2.png ├── vscode-shell.png └── vscodedemo.gif ├── life-expectancy-china-1960-2016.txt ├── markdown ├── 00.cover.md ├── 01.preface.md ├── 02.proof-of-work.md ├── Part.1.A.better.teachyourself.md ├── Part.1.B.why.start.from.learning.coding.md ├── Part.1.C.must.learn.sth.only.by.reading.md ├── Part.1.D.preparation.for.reading.md ├── Part.1.E.1.entrance.md ├── Part.1.E.2.values-and-their-operators.md ├── Part.1.E.3.controlflow.md ├── Part.1.E.4.functions.md ├── Part.1.E.5.strings.md ├── Part.1.E.6.containers.md ├── Part.1.E.7.files.md ├── Part.1.F.deal-with-forward-references.md ├── Part.1.G.The-Python-Tutorial-local.md ├── Part.2.A.clumsy-and-patience.md ├── Part.2.B.deliberate-practicing.md ├── Part.2.C.why-start-from-writing-functions.md ├── Part.2.D.1-args.md ├── Part.2.D.2-aargs.md ├── Part.2.D.3-lambda.md ├── Part.2.D.4-recursion.md ├── Part.2.D.5-docstrings.md ├── Part.2.D.6-modules.md ├── Part.2.D.7-tdd.md ├── Part.2.D.8-main.md ├── Part.2.E.deliberate-thinking.md ├── Part.3.A.conquering-difficulties.md ├── Part.3.B.1.classes-1.md ├── Part.3.B.2.classes-2.md ├── Part.3.B.3.decorator-iterator-generator.md ├── Part.3.B.4.regex.md ├── Part.3.B.5.bnf-ebnf-pebnf.md ├── Part.3.C.breaking-good-and-bad.md ├── Part.3.D.indispensable-illusion.md ├── Part.3.E.to-be-thorough.md ├── Part.3.F.social-selfteaching.md ├── Part.3.G.the-golden-age-and-google.md ├── Part.3.H.prevent-focus-drifting.md ├── Q.good-communiation.md ├── R.finale.md ├── README.md ├── S.whats-next.md ├── T-appendix.editor.vscode.md ├── T-appendix.git-introduction.md ├── T-appendix.jupyter-installation-and-setup.md ├── T-appendix.symbols.md └── TOC.md ├── my-notes ├── how-to-merge.md ├── 老生常谈的思考 ├── 自学笔记--emhodo.md └── 自学笔记(python篇)--emhodo.md ├── mycode.py ├── regex-target-text-sample.txt ├── results.txt ├── symbols.numbers ├── test-file.txt ├── that.py └── words_alpha.txt /.gitignore: -------------------------------------------------------------------------------- 1 | .python-version 2 | 3 | .DS_Store 4 | .ipynb_checkpoints/ 5 | __pycache__ 6 | **/.DS_Store 7 | **/.ipynb_chechpoints 8 | **/__pycache__ 9 | log.txt 10 | **/log.txt -------------------------------------------------------------------------------- /.vs/VSWorkspaceState.json: -------------------------------------------------------------------------------- 1 | { 2 | "ExpandedNodes": [ 3 | "", 4 | "\\from-readers\\lyric-self-teaching-stories", 5 | "\\my-notes" 6 | ], 7 | "SelectedNode": "\\my-notes\\how-to-merge.md", 8 | "PreviewInSolutionExplorer": false 9 | } -------------------------------------------------------------------------------- /.vs/slnx.sqlite: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/.vs/slnx.sqlite -------------------------------------------------------------------------------- /.vs/the-craft-of-selfteaching/v16/.suo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/.vs/the-craft-of-selfteaching/v16/.suo -------------------------------------------------------------------------------- /00.cover.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 自学是门手艺\n", 8 | "\n", 9 | "> One has no future if one couldn't teach themself[1].\n" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "**作者:李笑来**\n", 17 | "\n", 18 | "特别感谢**霍炬**([@virushuo](https://github.com/huo-ju))、**洪强宁**([@hongqn](https://github.com/hongqn)) 两位良师诤友在此书写作过程中给予我的巨大帮助!\n", 19 | "\n", 20 | "```python\n", 21 | "# pseudo-code of selfteaching in Python\n", 22 | "\n", 23 | "def teach_yourself(anything):\n", 24 | " while not create():\n", 25 | " learn()\n", 26 | " practice()\n", 27 | " return teach_yourself(another)\n", 28 | "\n", 29 | "teach_yourself(coding)\n", 30 | "```" 31 | ] 32 | }, 33 | { 34 | "cell_type": "markdown", 35 | "metadata": {}, 36 | "source": [ 37 | "## 目录\n", 38 | "\n", 39 | "> - [01.preface(**前言**)](01.preface.ipynb)\n", 40 | "> - [02.proof-of-work(**如何证明你真的读过这本书?**)](02.proof-of-work.ipynb)\n", 41 | "> - [Part.1.A.better.teachyourself(**为什么一定要掌握自学能力?**)](Part.1.A.better.teachyourself.ipynb)\n", 42 | "> - [Part.1.B.why.start.from.learning.coding(**为什么把编程当作自学的入口?**)](Part.1.B.why.start.from.learning.coding.ipynb)\n", 43 | "> - [Part.1.C.must.learn.sth.only.by.reading(**只靠阅读习得新技能**)](Part.1.C.must.learn.sth.only.by.reading.ipynb)\n", 44 | "> - [Part.1.D.preparation.for.reading(**开始阅读前的一些准备**)](Part.1.D.preparation.for.reading.ipynb)\n", 45 | "> - [Part.1.E.1.entrance(**入口**)](Part.1.E.1.entrance.ipynb)\n", 46 | "> - [Part.1.E.2.values-and-their-operators(**值及其相应的运算**)](Part.1.E.2.values-and-their-operators.ipynb)\n", 47 | "> - [Part.1.E.3.controlflow(**流程控制**)](Part.1.E.3.controlflow.ipynb)\n", 48 | "> - [Part.1.E.4.functions(**函数**)](Part.1.E.4.functions.ipynb)\n", 49 | "> - [Part.1.E.5.strings(**字符串**)](Part.1.E.5.strings.ipynb)\n", 50 | "> - [Part.1.E.6.containers(**数据容器**)](Part.1.E.6.containers.ipynb)\n", 51 | "> - [Part.1.E.7.files(**文件**)](Part.1.E.7.files.ipynb)\n", 52 | "> - [Part.1.F.deal-with-forward-references(**如何从容应对含有过多 “过早引用” 的知识?**)](Part.1.F.deal-with-forward-references.ipynb)\n", 53 | "> - [Part.1.G.The-Python-Tutorial-local(**官方教程:The Python Tutorial**)](Part.1.G.The-Python-Tutorial-local.ipynb)\n", 54 | "> - [Part.2.A.clumsy-and-patience(**笨拙与耐心**)](Part.2.A.clumsy-and-patience.ipynb)\n", 55 | "> - [Part.2.B.deliberate-practicing(**刻意练习**)](Part.2.B.deliberate-practicing.ipynb)\n", 56 | "> - [Part.2.C.why-start-from-writing-functions(**为什么从函数开始?**)](Part.2.C.why-start-from-writing-functions.ipynb)\n", 57 | "> - [Part.2.D.1-args(**关于参数(上)**)](Part.2.D.1-args.ipynb)\n", 58 | "> - [Part.2.D.2-aargs(**关于参数(下)**)](Part.2.D.2-aargs.ipynb)\n", 59 | "> - [Part.2.D.3-lambda(**化名与匿名**)](Part.2.D.3-lambda.ipynb)\n", 60 | "> - [Part.2.D.4-recursion(**递归函数**)](Part.2.D.4-recursion.ipynb)\n", 61 | "> - [Part.2.D.5-docstrings(**函数的文档**)](Part.2.D.5-docstrings.ipynb)\n", 62 | "> - [Part.2.D.6-modules(**保存到文件的函数**)](Part.2.D.6-modules.ipynb)\n", 63 | "> - [Part.2.D.7-tdd(**测试驱动的开发**)](Part.2.D.7-tdd.ipynb)\n", 64 | "> - [Part.2.D.8-main(**可执行的 Python 文件**)](Part.2.D.8-main.ipynb)\n", 65 | "> - [Part.2.E.deliberate-thinking(**刻意思考**)](Part.2.E.deliberate-thinking.ipynb)\n", 66 | "> - [Part.3.A.conquering-difficulties(**战胜难点**)](Part.3.A.conquering-difficulties.ipynb)\n", 67 | "> - [Part.3.B.1.classes-1(**类 —— 面向对象编程**)](Part.3.B.1.classes-1.ipynb)\n", 68 | "> - [Part.3.B.2.classes-2(**类 —— Python 的实现**)](Part.3.B.2.classes-2.ipynb)\n", 69 | "> - [Part.3.B.3.decorator-iterator-generator(**函数工具**)](Part.3.B.3.decorator-iterator-generator.ipynb)\n", 70 | "> - [Part.3.B.4.regex(**正则表达式**)](Part.3.B.4.regex.ipynb)\n", 71 | "> - [Part.3.B.5.bnf-ebnf-pebnf(**BNF 以及 EBNF**)](Part.3.B.5.bnf-ebnf-pebnf.ipynb)\n", 72 | "> - [Part.3.C.breaking-good-and-bad(**拆解**)](Part.3.C.breaking-good-and-bad.ipynb)\n", 73 | "> - [Part.3.D.indispensable-illusion(**刚需幻觉**)](Part.3.D.indispensable-illusion.ipynb)\n", 74 | "> - [Part.3.E.to-be-thorough(**全面 —— 自学的境界**)](Part.3.E.to-be-thorough.ipynb)\n", 75 | "> - [Part.3.F.social-selfteaching(**自学者的社交**)](Part.3.F.social-selfteaching.ipynb)\n", 76 | "> - [Part.3.G.the-golden-age-and-google(**这是自学者的黄金时代**)](Part.3.G.the-golden-age-and-google.ipynb)\n", 77 | "> - [Part.3.H.prevent-focus-drifting(**避免注意力漂移**)](Part.3.H.prevent-focus-drifting.ipynb)\n", 78 | "> - [Q.good-communiation(**如何成为优秀沟通者**)](Q.good-communication.ipynb)\n", 79 | "> - [R.finale(**自学者的终点**)](R.finale.ipynb)\n", 80 | "> - [S.whats-next(**下一步干什么?**)](S.whats-next.ipynb)\n", 81 | "> - [T-appendix.editor.vscode(**Visual Studio Code 的安装与配置**)](T-appendix.editor.vscode.ipynb)\n", 82 | "> - [T-appendix.git-introduction(**Git 简介**)](T-appendix.git-introduction.ipynb)\n", 83 | "> - [T-appendix.jupyter-installation-and-setup(**Jupyterlab 的安装与配置**)](T-appendix.jupyter-installation-and-setup.ipynb)\n", 84 | "> - [T-appendix.symbols(**这些符号都代表什么?**)](T-appendix.symbols.ipynb)" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "本书的版权协议为 [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)。\n", 92 | "\n", 93 | "![CC-BY-NC-ND](images/CC-BY-NC-ND.png)\n", 94 | "\n", 95 | "-----\n", 96 | "**脚注**\n", 97 | "\n", 98 | "[1]:['Themselves' or 'themself'? -- Oxford Dictionary](https://en.oxforddictionaries.com/usage/themselves-or-themself)\n", 99 | "\n", 100 | "↑Back to Content↑" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Next Page" 108 | ] 109 | } 110 | ], 111 | "metadata": { 112 | "kernelspec": { 113 | "display_name": "Python 3", 114 | "language": "python", 115 | "name": "python3" 116 | }, 117 | "language_info": { 118 | "codemirror_mode": { 119 | "name": "ipython", 120 | "version": 3 121 | }, 122 | "file_extension": ".py", 123 | "mimetype": "text/x-python", 124 | "name": "python", 125 | "nbconvert_exporter": "python", 126 | "pygments_lexer": "ipython3", 127 | "version": "3.8.3" 128 | }, 129 | "toc-autonumbering": false 130 | }, 131 | "nbformat": 4, 132 | "nbformat_minor": 2 133 | } 134 | -------------------------------------------------------------------------------- /Part.1.C.must.learn.sth.only.by.reading.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "toc-hr-collapsed": false 7 | }, 8 | "source": [ 9 | "# 只靠阅读习得新技能" 10 | ] 11 | }, 12 | { 13 | "cell_type": "markdown", 14 | "metadata": {}, 15 | "source": [ 16 | "习得自学能力的终极目标就是:\n", 17 | "\n", 18 | "> 有能力**只靠阅读**就能习得新技能。\n", 19 | "\n", 20 | "退而求其次,是 “尽量只靠阅读就习得新技能” —— 当然,刚开始的时候可能需要有人陪伴,一起学,一起讨论,一起克服困难…… 但就是要摆脱 “没人教,没人带,没人逼,就彻底没戏” 的状态。" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "小时候总是听大人说:\n", 28 | "\n", 29 | "> 不是什么东西都可以从书本里学到的……\n", 30 | "\n", 31 | "一度,我觉得他们说的有道理。再后来,隐约感觉这话哪儿有毛病,但竟然又感觉无力反驳……\n", 32 | "\n", 33 | "那时,真被他们忽悠到了;后来,也差点被他们彻底忽悠到!\n", 34 | "\n", 35 | "幸亏后来我渐渐明白,且越来越相信:\n", 36 | "\n", 37 | "> 自己生活工作学习上遇到的所有疑问,书本里应该都有答案 —— 起码有所参考。\n", 38 | "\n", 39 | "“不是什么东西都可以从书本里学到的……” 这话听起来那么有道理,只不过是因为自己读书**不够多**、**不够对**而已。\n", 40 | "\n", 41 | "过了 25 岁,我放弃了读小说,虚构类作品,我只选择看电影;而非虚构类作品,我选择尽量只读英文书,虽然那时候买起来很贵也很费劲,但我觉得值 —— 英文世界和中文世界的文化风格略有不同。在英文世界里,你看到的正常作者好像更多地把 “通俗易懂”、“逻辑严谨” 当作最基本的素养;而在中文世界里,好像 “故弄玄虚”、“偷梁换柱” 更常见一些;在英文世界里,遇到读不懂的东西可以很平静地接受自己暂时的愚笨,心平气和地继续努力就好;在中文世界里,遇到装神弄鬼欺世盗名的,弄不好最初根本没认出来,到最后跟 “认贼作父” 一样令人羞辱难当不堪回首。\n", 42 | "\n", 43 | "说实话,我真觉得这事跟崇洋媚外没什么关系。我是朝鲜族,去过韩国,真觉得韩国的书更没法看(虽然明显是个人看法)…… 2015 年年底,我的律师告诉我,美国移民就快帮我办下来了,可那时候我开始觉得美国政府也各种乱七八糟,于是决定停止办理。我是个很宅的人,除了餐馆基本上哪儿都不去,陪家人朋友出去所谓旅游的时候,我只不过是换个房间继续宅着…… 可这些都不是重点,重点在于:\n", 44 | "\n", 45 | "> **知识原本就应该无国界**…… 不是吗?不是吗!\n", 46 | "\n", 47 | "再说,这些年我其实还读了不少中国人写的英文书呢,比如,张纯如的书很值得一看;郑念的 Life and Death in Shanghai,真的很好很好。我也读了不少老外写的关于中国的书 —— 这些年我一直推荐费正清的剑桥中国史(The Cambridge History of China),当然有中文版的,不过,能读英文版的话感受很不一样。\n", 48 | "\n", 49 | "当然,英文书里同样烂书也很多,烂作者也同样一大堆,胡说八道欺世盗名的一大串…… 但总体上来看,非小说类著作质量的确更高一点。\n", 50 | "\n", 51 | "还有,英语在科学研究领域早已成为 “主导语言”(Dominant Language)也是不争的事实。不过,英语成为主导语言的结果,就是英语本身被不断 “强奸”,外来语越来越多,“Long time no see” 被辞典收录就是很好的例子。事实上,英语本身就是个大杂烩……\n", 52 | "\n", 53 | "![Joseph M. Williams’ research visualized (top 10,000 words).](images/Joseph-M-Williams-research-visualized.png)\n", 54 | "\n", 55 | "读书越多越明白读书少会被忽悠…… 很多人真的会大头捣蒜一般地认同 “不是什么东西都可以从书本里学到的……”\n", 56 | "\n", 57 | "另外,很多人在如此教导小朋友的时候,往往是因为 “人心叵测” 啊,“江湖险恶” 啊,所以害怕小朋友吃亏。可事实上,如若说,人间那些勾心斗角的事貌似从书本里学不来的话,其实也不过还是历史书看少了 —— 勾心斗角的套路历史上全都被反复用过了。倒是有本中文书值得吐血推荐,民国时代的作者连阔如先生写的《江湖丛谈》,粗略扫过你就知道了,江湖那点事,也早就有人给你里里外外翻了个遍…… 只不过这书不太容易买到就是了。\n", 58 | "\n", 59 | "我也遇到过这样的反驳:\n", 60 | "\n", 61 | "> 书本能教会你做生意吗?!\n", 62 | "\n", 63 | "说实话,去回驳这个反驳还真挺难,因为反驳者是脑容量特别有限才能说出这种话 —— 世界上有那么多商学院都是干嘛的?搞得它们好像不存在一样。首先,它们的存在说明,商业这事是有迹可循的,是可学习的;其次,商业类书籍非常多,是非虚构类书籍中的一大品类;更为重要的是,做生意这事,看谁做 —— 有本事(即,比别人拥有更多技能)的人做生意和没本事的人做生意,用同样的商业技巧,能有一样的效果吗?最后啊,这世界在这方面从来没有变过:一技傍身的人,总是不愁生活……\n", 64 | "\n", 65 | "更为重要的是,这才几年啊,互联网本身已经成了一本大书 —— 关于全世界的一整本大书。仅仅是 10 多年前,大约在 2008 年前后,经过几年发展的 Wikipedia 被众多西方大学教授们群起而攻,指责它错误百出…… 可现在呢?Wikipedia 好像有天生的自我修复基因,它变得越来越值得信赖,越来越好用。\n", 66 | "\n", 67 | "七零后八零后长大的过程中,还经常被父母无故呵斥:“怎么就你事这么多!” 或者无奈敷衍:“等你长大了就明白了……” 九零后、零零后呢?他们很少有什么疑问需要向父母提问,直接问搜索引擎,效果就是父母们天天被惊到甚至吓到。最近两年更不一样了,我有朋友在旧金山生活,他的孩子整天跟 Google 说话,有点什么问题,就直接 “Hey Google...”\n", 68 | "\n", 69 | "我长大的那个年代,一句 “通过阅读了解世界” 好像还是很抽象甚至很不现实的话,现在呢?现在,除了阅读之外,你还能想出什么更有效的方法吗?反正我想不出。\n", 70 | "\n", 71 | "有个很有趣的现象:\n", 72 | "\n", 73 | "> 人么,只要识字,就忍不住阅读……\n", 74 | "\n", 75 | "只不过,人们阅读的选择很不同而已。有自学能力的人和没有自学能力的人,在这一点上很容易分辨:\n", 76 | "\n", 77 | "> * 有自学能力的人,选择阅读 “有繁殖能力” 的内容;\n", 78 | "> * 没有自学能力的人,阅读只是为了消磨时光……\n", 79 | "\n", 80 | "我把那些能给你带来新视野,能让你改变思考模式,甚至能让你拥有一项新技能的内容称之为 “有繁殖能力的内容”。\n", 81 | "\n", 82 | "人都一样,拥有什么样的能力之后,就会忍不住去用,甚至总是连下意识中也要用。\n", 83 | "\n", 84 | "那些靠阅读机器算法推送的内容而杀时间的人,恰恰就是因为他们有阅读能力才去不断地读,读啊读,像是那只被打了兴奋剂后来死在滚轮上的小白鼠。如果这些人哪怕有一点点自学能力,那么他们很快就会分辨出自己正在阅读的东西不会刺激自己的产出,只会消磨自己的时间;那么,他们就会主动放弃阅读那些杀时间的内容,把那时间和精力自然而然地用在筛选有繁殖能力的内容,让自己进步,让自己习得更多技能上去了。\n", 85 | "\n", 86 | "所以,只要你有一次 “**只靠阅读习得一项新技能**” 的经验,你就变成另外一个人了。你会不由自主、哪怕下意识里都会去运用你新习得的能力…… 从这个角度看,自学很上瘾!能上瘾,却不仅无害,还好处无穷,这样的好事,恐怕也就这一个了罢。\n", 87 | "\n", 88 | "我有过只靠阅读学会游泳的经历…… 听起来不像真的吧?更邪门的是,罗永浩同学的蛙泳,是我站在游泳池边,仅靠言语讲解,就让他从入水就扑腾开始三十分钟之内可以开始蛙泳的 —— 虽然当天他第一次蛙泳,一个来回五十米都坚持不下来。\n", 89 | "\n", 90 | "仅靠阅读学会新技能不仅是可能的,并且,你随后会发现的真相是:\n", 91 | "\n", 92 | "> 绝大多数情况下,没人能教你,也不一定有人愿意教你…… 到最后,你想学会或你必须学会什么东西的时候,**你只能靠阅读!** —— 因为其实你谁都靠不上……\n", 93 | "\n", 94 | "我有很多偶像,英国数学家乔治・布尔就是其中一个 —— 因为他就是个基本上只靠阅读自学成才的人。十八、九岁,就自学了微积分 —— 那是将近两百年前,没有 Google,没有 Wikipedia…… 然后他还自己创办了学校,给自己打工…… 从来没有上过大学,后来却被皇家学院聘请为该学院第一个数学教授。然后,人家发明的布尔代数,在百年之后引发了信息革命…… 达芬奇也是这样的人 —— 要说惨,他比所有人都惨…… 因为几乎从一开始就貌似没有谁有资格有能力教他。\n", 95 | "\n", 96 | "这些例子都太遥远了。给你讲个我身边的人,我亲自打过很长时间交道的人 —— 此人姓邱,人称邱老板。\n", 97 | "\n", 98 | "邱老板所写的区块链交易所引擎,在 Github 上用的是个很霸气的名字,“[貔貅](https://github.com/peatio/peatio)”(英文用了一个生造的词,Peatio)—— 这个 Repo 至 2019 年春节的时候,总计有 2,913 个 Star,有 2,150 个 Fork…… 绝对是全球这个领域中最受关注的开源项目。2017 年 9 月,云币应有关部门要求关闭之前,是全球排名前三的区块链交易所。\n", 99 | "\n", 100 | "邱老板当年上学上到几年级呢?初中未读完,所以,跟他聊天随口说成语是很有负担的,因为他真的可能听不懂…… 然而,他的编程、他的英语,全是自学的…… 学到什么地步呢?学到可以创造极有价值的商业项目的地步。他什么学习班都没上过,全靠阅读 —— 基本上只读互联网这本大书。" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "讲真,你没有选择,只靠阅读习得新技能,这是你唯一的出路。" 108 | ] 109 | }, 110 | { 111 | "cell_type": "markdown", 112 | "metadata": {}, 113 | "source": [ 114 | "[Next Page](Part.1.D.preparation.for.reading.ipynb)" 115 | ] 116 | } 117 | ], 118 | "metadata": { 119 | "kernelspec": { 120 | "display_name": "Python 3", 121 | "language": "python", 122 | "name": "python3" 123 | }, 124 | "language_info": { 125 | "codemirror_mode": { 126 | "name": "ipython", 127 | "version": 3 128 | }, 129 | "file_extension": ".py", 130 | "mimetype": "text/x-python", 131 | "name": "python", 132 | "nbconvert_exporter": "python", 133 | "pygments_lexer": "ipython3", 134 | "version": "3.8.3" 135 | } 136 | }, 137 | "nbformat": 4, 138 | "nbformat_minor": 2 139 | } 140 | -------------------------------------------------------------------------------- /Part.1.D.preparation.for.reading.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 开始阅读前的一些准备" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "## 内容概要" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "关于 Python 编程的第一部分总计 7 章,主要内容概括为:\n", 22 | "\n", 23 | "> 1. 以布尔值为入口开始理解程序本质\n", 24 | "> 1. 了解值的分类和运算方法\n", 25 | "> 1. 简要了解流程控制的原理\n", 26 | "> 1. 简要了解函数的基本构成\n", 27 | "> 1. 相对完整地了解字符串的操作\n", 28 | "> 1. 了解各种容器的基础操作\n", 29 | "> 1. 简要了解文件的读写操作" 30 | ] 31 | }, 32 | { 33 | "cell_type": "markdown", 34 | "metadata": {}, 35 | "source": [ 36 | "## 阅读策略" 37 | ] 38 | }, 39 | { 40 | "cell_type": "markdown", 41 | "metadata": {}, 42 | "source": [ 43 | "首先,不要试图一下子就全部搞懂。这不仅很难,**在最初的时候也完全没必要**。\n", 44 | "\n", 45 | "因为这部分的知识结构中,充满了 “过早引用”。请在第一遍粗略完成第 1 部分中的 E1 ~ E7 之后,再去阅读《[如何从容应对 “过早引用”?](Part.1.F.deal-with-forward-references.ipynb)》。\n", 46 | "\n", 47 | "其次,这一部分,注定要**反复阅读若干遍**。\n", 48 | "\n", 49 | "在开始之前,要明确这一部分的阅读目标。\n", 50 | "\n", 51 | "这一部分的目标,不是让你读完之后就可以开始写程序;也不是让你读完之后就对编程或者 Python 编程有了完整的了解,甚至不是让你真的学会什么…… 这一部分的目标,只是让你 “**脱盲**”。\n", 52 | "\n", 53 | "不要以为脱盲是很容易的事情。你看,所有人出生的时候,都天然是 “文盲”;人们要上好多年的学,才能够真正 “脱盲” —— 仔细想想吧,小学毕业的时候,所有人就真的彻底脱盲了吗?\n", 54 | "\n", 55 | "以中文脱盲为例,学字的同时,还要学习笔划;为了学更多的字,要学拼音,要学如何使用《新华字典》……\n", 56 | "\n", 57 | "学会了一些基础字之后,要学更多的词,而后在练习了那么多造词造句之后,依然会经常用错…… 你看,脱盲,和阅读能力强之间距离很长呢;不仅如此,阅读能力强和写作能力强之间的距离更长……\n", 58 | "\n", 59 | "反复阅读这一部分的结果是:\n", 60 | "\n", 61 | "> * 你对基本概念有了一定的了解\n", 62 | "> * 你开始有能力相对轻松地阅读部分官方文档\n", 63 | "> * 你可以读懂一些简单的代码\n", 64 | "\n", 65 | "仅此而已。" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "## 心理建设" 73 | ] 74 | }, 75 | { 76 | "cell_type": "markdown", 77 | "metadata": {}, 78 | "source": [ 79 | "当我们开始学习一项新技能的时候,我们的大脑会不由自主地紧张。可这只不过是多年之间在学校里不断受挫的积累效应 —— 学校里别的地方不一定行,可有个地方特别行:给学生制造全方位、无死角、层层递进的挫败感。\n", 80 | "\n", 81 | "可是,你要永远记住两个字:\n", 82 | "\n", 83 | "> 别怕!\n", 84 | "\n", 85 | "用四个字也行:\n", 86 | "\n", 87 | "> 啥也别怕!\n", 88 | "\n", 89 | "六个字也可以:\n", 90 | "\n", 91 | "> 没什么可怕的!\n", 92 | "\n", 93 | "我遇到最多的孱弱之语大抵是这样的:\n", 94 | "\n", 95 | "> 我一个文科生……\n", 96 | "\n", 97 | "哈哈,从某个层面望过去,其实吧,编程既不是文科也不是理科…… 它更像是 “手工课”。你越学就越清楚这个事实,它就好像是你做木工一样,学会使用一个工具,再学会使用另外一个工具,其实总共就没多少工具。然后,你更多做的是各种拼接的工作,至于能做出什么东西,最后完全靠你的想象力……\n", 98 | "\n", 99 | "十来岁的孩子都可以学会的东西,你怕什么?\n", 100 | "\n", 101 | "**别怕**,无论说给自己,还是讲给别人,都是一样的,它可能是人生中最重要的鼓励词。" 102 | ] 103 | }, 104 | { 105 | "cell_type": "markdown", 106 | "metadata": {}, 107 | "source": [ 108 | "## 关于这一部分内容中的代码" 109 | ] 110 | }, 111 | { 112 | "cell_type": "markdown", 113 | "metadata": {}, 114 | "source": [ 115 | "所有的代码,都可以在选中代码单元格(Code Cell)之后,按快捷键 `⇧ ⏎` 或 `^ ⏎` 执行,查看结果。\n", 116 | "\n", 117 | "少量执行结果太长的代码,其输出被设置成了 “Scrolled”,是可以通过触摸板或鼠标滑轮上下滑动的。\n", 118 | "\n", 119 | "为了避免大量使用 `print()` 才能看到输出结果,在很多的代码单元格中,开头插入了以下代码:\n", 120 | "\n", 121 | "```python\n", 122 | "from IPython.core.interactiveshell import InteractiveShell\n", 123 | "InteractiveShell.ast_node_interactivity = \"all\"\n", 124 | "```\n", 125 | "你可以暂时忽略它们的意义和工作原理。注意:有时,你需要在执行第二次的时候,才能看到全部输出结果。\n", 126 | "\n", 127 | "另外,有少量代码示例,为了让读者每次执行的时候看到不同的结果,使用了随机函数,为其中的变量赋值,比如:\n", 128 | "\n", 129 | "```python\n", 130 | "import random\n", 131 | "r = random.randrange(1, 1000)\n", 132 | "```\n", 133 | "\n", 134 | "同样,你可以暂时忽略它们的意义和工作原理;只需要知道因为有它们在,所以每次执行那个单元格中的代码会有不同的结果就可以了。\n", 135 | "\n", 136 | "如果你不是直接在网站上浏览这本 “书”、或者不是在阅读印刷版,而是在本地自己搭建 Jupyterlab 环境使用,那么请参阅附录《[Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.ipynb)》。\n", 137 | "\n", 138 | "> **注意**:尤其需要仔细看看《[Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.ipynb)》的《关于 Jupyter lab themes》这一小节 —— 否则,阅读体验会有很大差别。\n", 139 | "\n", 140 | "另外,如果你使用的是 [nteract](https://nteract.io) 桌面版 App 浏览 `.ipynb` 文件,那么有些使用了 `input()` 函数的代码是无法在 nteract 中执行的。" 141 | ] 142 | }, 143 | { 144 | "cell_type": "markdown", 145 | "metadata": {}, 146 | "source": [ 147 | "[Next Page](./Part.1.E.1.entrance.ipynb)" 148 | ] 149 | } 150 | ], 151 | "metadata": { 152 | "kernelspec": { 153 | "display_name": "Python 3", 154 | "language": "python", 155 | "name": "python3" 156 | }, 157 | "language_info": { 158 | "codemirror_mode": { 159 | "name": "ipython", 160 | "version": 3 161 | }, 162 | "file_extension": ".py", 163 | "mimetype": "text/x-python", 164 | "name": "python", 165 | "nbconvert_exporter": "python", 166 | "pygments_lexer": "ipython3", 167 | "version": "3.8.3" 168 | } 169 | }, 170 | "nbformat": 4, 171 | "nbformat_minor": 2 172 | } 173 | -------------------------------------------------------------------------------- /Part.2.B.deliberate-practicing.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 刻意练习" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "在自学的过程中,总是有一些部分需要刻意练习。就好像小时候我们学习汉字,有些人总是把 “武” 这个字上加上一个撇 —— 对他们来说,不去写那个不该有的撇,就是需要刻意练习的。另外一些人倒是不在这个字上出错,但候和侯傻傻地分不清楚(类似的例子不计其数),那么,对他们来说就有了另外需要刻意练习的地方……" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "手艺这个东西,尤其需要刻意练习。我们说,手艺么,主要是靠时间…… 这里的 “时间”,准确地讲,就是 “刻意练习” 的时间,而不是任何时间。\n", 22 | "\n", 23 | "我当过很长时间的英语老师。异常苦于一件事:最有用的道理最没人听。\n", 24 | "\n", 25 | "学英语根本就不应该那么难,学了十六年也学不明白 —— 至于嘛!然而,最简单的道理,人们就是听不进去。他们之所以不行,就是因为从未刻意练习。学英语最简单的刻意练习就是朗读。每天朗读一小时,一百天下来就会超越绝大多数人,也会超越自己原本可能永远跨不过去的那个坎 —— 神奇的是,朗读什么无所谓,反正现在有声书那么多…… 更神奇的是,刚开始朗读得好不好听,甚至好不好都无所谓,反正没几天就能体会到大幅进步…… 最神奇的是,这么简单的事,99.99% 的人不做 —— 你身在中国,能理解这个比例真的没有夸张。\n", 26 | "\n", 27 | "顺带推荐一下王渊源(John Gordan)的微信公众号:\n", 28 | "\n", 29 | "> 清晨朗读会\n", 30 | "\n", 31 | "到 2019 年 2 月 21 日,王渊源同学的清晨朗读会带着大伙朗读了第 1000 天……" 32 | ] 33 | }, 34 | { 35 | "cell_type": "markdown", 36 | "metadata": {}, 37 | "source": [ 38 | "许多年前,资质平庸的我,一直苦恼一件事:\n", 39 | "\n", 40 | "> * 为什么自己无论干什么都笨手笨脚、差这儿差那儿的……\n", 41 | "> * 为什么与此同时,总是能看到另外一些人,给人感觉 “一出手就是高手” 呢?!\n", 42 | "\n", 43 | "这事折磨了我好多年…… 直到后来我当了老师,每年面前流过几万名学生之后,我才 “羞耻” 地反应过来:\n", 44 | "\n", 45 | "> * 我花在刻意练习上的时间**太少**了;\n", 46 | "> * 并且,也没有**刻意思考**哪些地方我应该去刻意练习。\n", 47 | "\n", 48 | "而那些看起来 “一出手就是高手” 的人,则恰恰相反,他们不仅花很多时间刻意练习,还总是刻意思考在哪些地方尤其要刻意练习 —— 就是这一点差别造成了那么大的差距。\n", 49 | "\n", 50 | "比如,小时候玩琴,因为手骨摔断了,于是就中断了很多刻意练习 —— 后来换成拨片之后,也习惯不好,不做很多基础练习,只是顺着感觉 “胡搞瞎搞”…… 于是,我的琴艺永远是自娱自乐也就刚刚够用的水准,永远上不了下一个台阶。我认识的人之中,许岑同学在这方面就是我这种情况的反向典范。\n", 51 | "\n", 52 | "然而,我深刻地意识到,在另外一些地方,若是再 “混” 下去,那这辈子就别想有什么名堂了。所以,我就下决心在必要的地方一定要刻意地练习。印象中我第一个应用这种思考模式与决心的地方就是写书。我花了很长时间去准备第一本书,并且刻意地思考在哪些地方应该刻意地用力 —— 比如,在取书名这件在别人眼里可能并不是很重要的事上,我每天都琢磨,前后换了二十几个名字,最终选定…… 其后每一本出版的书籍,在书名选择上我都 “殚精竭虑” —— 最终的结果是,我的第一本书就是畅销书、长销书 —— 后面的每一本都是。\n", 53 | "\n", 54 | "对,所谓的 “混”,解释很简单:\n", 55 | "\n", 56 | "> **不做刻意练习的人就是在混时间**。\n", 57 | "\n" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "需要刻意练习的地方,因人而异。有的人就是不可能让 “武” 字带把刀,不需要刻意练习,但另外一些人不是。有些人就是朗读十分钟的效果跟别人朗读一小时的效果一样地好,但更多的人并不是……\n", 65 | "\n", 66 | "然而,这并不是所谓的 “天分” 差异,这大抵上只相当于正态分布坐标略不相同而已。每个人都一样,都有各自必须刻意练习的地方,都有对别人来说无比容易可偏偏对自己来说就是很难的地方,而且,在这件事上,大家的点虽然各不相同,但总体上需要刻意练习的部分比例都差不多 —— 虽然说不清楚那个比例到底是多少。\n", 67 | "\n", 68 | "比如,在学一门新的编程语言时,我常常做这样的刻意练习:\n", 69 | "\n", 70 | "> **在纸上用笔写程序……**\n", 71 | "\n", 72 | "而后,看着纸上的程序,把自己的大脑当作解析器,去判断每一句执行后的结果……\n", 73 | "\n", 74 | "反复确认之后,再在编辑器里输入这个程序 —— 用很慢的速度,确保自己的输入无误……\n", 75 | "\n", 76 | "然后再一运行,十有八九出错 —— 要再反复检查修改很多次才能顺利执行到最后……\n", 77 | "\n", 78 | "为什么要这么做呢?因为我发现自己一旦学另外一个语言的时候,自己的大脑就会经常把这个新的语言与之前学过的其他语言相混淆,这很痛苦。我必须想出一个办法,让之前的也好,之后的也罢,干脆刻在自己的脑子里,不可能相互混淆。\n", 79 | "\n", 80 | "我相信不是所有人都有我这样的烦恼和痛苦,虽然他们在我不烦恼不痛苦的地方也可能烦恼痛苦……\n", 81 | "\n", 82 | "然而,于我来讲,这就是**我需要刻意练习**的地方 —— 这也是我**刻意思考**之后才找到的需要刻意练习的地方。\n", 83 | "\n", 84 | "你也一样。你需要刻意练习的地方,需要你自己去刻意思考 —— 你和别人不一样,没有人和你一样,就这样。\n", 85 | "\n", 86 | "这种事情,过去还真的是所谓 “书本上学不到” 的东西 —— 因为没有哪个作者能做到 “遍历世上所有人的所有特殊情况”…… 不过,互联网这本大书貌似正在突破这种限制,因为有无数的作者在写书,每个人所关注的点也不一样,再加上搜索引擎,所以,你总是可以在互联网这本大书中找到 “竟然与我一样的人”!" 87 | ] 88 | }, 89 | { 90 | "cell_type": "markdown", 91 | "metadata": {}, 92 | "source": [ 93 | "于是,你可能感受到了,其实吧,所谓 “刻意练习”,其实是 “刻意思考哪里需要刻意练习” 之后最自然不过的事情 —— 所以,**“刻意思考” 才是关键。**\n", 94 | "\n", 95 | "应对策略很简单:\n", 96 | "\n", 97 | "> 准备个专门的地方记录\n", 98 | "\n", 99 | "我现在用的最多的就是 iPhone 上的 Notes,一旦遇到什么 “疑似需要刻意练习” 的点,就顺手记录在那里以防不小心忘记或者不小心遗漏。\n", 100 | "\n", 101 | "而后有时间的时候就拿出来看看,排列一下优先级,琢磨一下刻意练习的方式,而后找时间刻意练习,如此这般,做到 “尽量不混日子”……\n", 102 | "\n", 103 | "有时候,刻意练习是很容易的,比如,为了让自己记住当前正在学习的编程语言的语法规则,直至 “刻在脑子里一般”,需要做的无非是把编辑器中的 “Auto completion”(自动补全)先关掉三个月 —— 麻烦一点就麻烦一点,坚决不让 Tab 键帮自己哗啦哗啦写上一大片…… 那不叫麻烦,那叫刻意练习。\n", 104 | "\n", 105 | "人们常说:\n", 106 | "\n", 107 | "> 凡事,就怕**琢磨**……\n", 108 | "\n", 109 | "那些高手,无一例外都是善于琢磨的人…… 可是,他们在琢磨什么呢?为什么他们会琢磨那些事呢?\n", 110 | "\n", 111 | "你看,所谓的琢磨,其实真的不是很难,只不过,在此之前,你不知道该琢磨什么而已,一旦知道了,剩下的都再自然不过,都会自然而然地发生 —— 事实上,所谓的差别差距,只不过一线间而已。" 112 | ] 113 | }, 114 | { 115 | "cell_type": "markdown", 116 | "metadata": {}, 117 | "source": [ 118 | "Next Page" 119 | ] 120 | } 121 | ], 122 | "metadata": { 123 | "kernelspec": { 124 | "display_name": "Python 3", 125 | "language": "python", 126 | "name": "python3" 127 | }, 128 | "language_info": { 129 | "codemirror_mode": { 130 | "name": "ipython", 131 | "version": 3 132 | }, 133 | "file_extension": ".py", 134 | "mimetype": "text/x-python", 135 | "name": "python", 136 | "nbconvert_exporter": "python", 137 | "pygments_lexer": "ipython3", 138 | "version": "3.8.3" 139 | } 140 | }, 141 | "nbformat": 4, 142 | "nbformat_minor": 2 143 | } 144 | -------------------------------------------------------------------------------- /Part.2.C.why-start-from-writing-functions.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 为什么从函数开始?" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "读完第一部分之后,你多多少少已经 “写” 了一些程序,虽然我们总是说,“这就是让你脱盲”;也就是说,从此之后,你多多少少能够读懂程序,这就已经很好了。\n", 15 | "\n", 16 | "可是你无论如何都避免不了已经写了一些,虽然,那所谓的 “写”,不过是 “改” 而已 —— 但毕竟也是一大步。\n", 17 | "\n", 18 | "绝大多数编程书籍并不区分学习者的 “读” 与 “写” 这两个实际上应该分离的阶段 —— 虽然现实中这两个阶段总是多多少少重叠一部分。\n", 19 | "\n", 20 | "在一个比较自然的过程中,我们总是先学会阅读,而后才开始练习写作;并且,最终,阅读的量一定远远大于写作的量 —— 即,输入远远大于输出。当然,貌似也有例外。据说,香港作家倪匡,他自己后来很少读书,每天咣当咣当地像是打扫陈年旧物倒垃圾一样写作 —— 他几乎是全球最具产量的畅销小说作家,貌似地球另外一端的史蒂芬・金都不如他多。又当然,他的主要输入来自于他早年丰富的人生经历,人家读书,他阅世,所以,实际上并不是输入很少,恰恰相反,是输入太多……\n", 21 | "\n", 22 | "所以,正常情况下,输入多于输出,或者,输入远远多于输出,不仅是自然现象,也是无法改变的规则。\n", 23 | "\n", 24 | "于是,我在安排内容的时候,也刻意如此安排。\n", 25 | "\n", 26 | "第一部分,主要在于启动读者在编程领域中的 “阅读能力”,到第二部分,才开始逐步启动读者在编程领域中的 “写作能力”。\n", 27 | "\n", 28 | "在第二部分启动之前,有时间有耐心的读者可以多做一件事情。\n", 29 | "\n", 30 | "Python 的代码是开源的,它的代码仓库在 Github 上:\n", 31 | "\n", 32 | "> https://github.com/python/\n", 33 | "\n", 34 | "在这个代码仓库中,有一个目录下,保存着若干 Python Demo 程序:\n", 35 | "\n", 36 | "> https://github.com/python/cpython/tree/master/Tools/demo\n", 37 | "\n", 38 | "这个目录下的 README 中有说明:\n", 39 | "\n", 40 | "> This directory contains a collection of demonstration scripts for\n", 41 | "> various aspects of Python programming.\n", 42 | ">\n", 43 | "> * `beer.py` Well-known programming example: Bottles of beer.\n", 44 | "> * `eiffel.py` Python advanced magic: A metaclass for Eiffel post/preconditions.\n", 45 | "> * `hanoi.py` Well-known programming example: Towers of Hanoi.\n", 46 | "> * `life.py` Curses programming: Simple game-of-life.\n", 47 | "> * `markov.py` Algorithms: Markov chain simulation.\n", 48 | "> * `mcast.py` Network programming: Send and receive UDP multicast packets.\n", 49 | "> * `queens.py` Well-known programming example: N-Queens problem.\n", 50 | "> * `redemo.py` Regular Expressions: GUI script to test regexes.\n", 51 | "> * `rpython.py` Network programming: Small client for remote code execution.\n", 52 | "> * `rpythond.py` Network programming: Small server for remote code execution.\n", 53 | "> * `sortvisu.py` GUI programming: Visualization of different sort algorithms.\n", 54 | "> * `ss1.py` GUI/Application programming: A simple spreadsheet application.\n", 55 | "> * `vector.py` Python basics: A vector class with demonstrating special methods.\n", 56 | "\n", 57 | "最起码把这其中的以下几个程序都精读一下,看看你自己的理解能力:\n", 58 | "\n", 59 | "> * [beer.py](https://github.com/python/cpython/blob/master/Tools/demo/beer.py) Well-known programming example: Bottles of beer.\n", 60 | "> * [eiffel.py](https://github.com/python/cpython/blob/master/Tools/demo/eiffel.py) Python advanced magic: A metaclass for Eiffel post/preconditions.\n", 61 | "> * [hanoi.py](https://github.com/python/cpython/blob/master/Tools/demo/hanoi.py) Well-known programming example: Towers of Hanoi.\n", 62 | "> * [life.py](https://github.com/python/cpython/blob/master/Tools/demo/life.py) Curses programming: Simple game-of-life.\n", 63 | "> * [markov.py](https://github.com/python/cpython/blob/master/Tools/demo/markov.py) Algorithms: Markov chain simulation.\n", 64 | "> * [queens.py](https://github.com/python/cpython/blob/master/Tools/demo/queens.py) Well-known programming example: N-Queens problem.\n", 65 | "\n", 66 | "就算读不懂也没关系,把读不懂的部分标记下来,接下来就可以 “带着问题学习”……\n", 67 | "\n", 68 | "在未来的时间里,一个好的习惯就是,有空了去读读别人写的代码 —— 理解能力的提高,就靠这个了。你会发现这事跟其他领域的学习没什么区别。你学英语也一样,读多了,自然就读得快了,理解得快了,并且在那过程中自然而然地习得了很多 “句式”,甚至很多 “说理的方法”、“讲故事的策略”…… 然后就自然而然地会写了,从能写一点开始,慢慢到 “很能写”!" 69 | ] 70 | }, 71 | { 72 | "cell_type": "markdown", 73 | "metadata": {}, 74 | "source": [ 75 | "为了顺利启动第一部分的 “阅读”,特意找了个不一样的入口,“布尔运算”;第二部分,从 “阅读” 过渡到 “写作”,我也同样特意寻找了一个不一样的入口:**从函数开始写起**。\n", 76 | "\n", 77 | "从小入手,从来都是自学的好方法。我们没有想着一上来就写程序,而是写 “子程序”、“小程序”、“短程序”。从结构化编程的角度来看,写函数的一个基本要求就是:\n", 78 | "\n", 79 | "> - 完成一个功能;\n", 80 | "> - 只完成一个功能;\n", 81 | "> - 没有任何错误地只完成一个功能……\n", 82 | "\n", 83 | "然而,即便是从小入手,任务也没有变得过分简单。其中涉及的话题理解起来并不容易,尽管我们尽量用最简单的例子。涉及的话题有:\n", 84 | "\n", 85 | "> - 参数的传递\n", 86 | "> - 多参数的传递\n", 87 | "> - 匿名函数以及函数的别称\n", 88 | "> - 递归函数\n", 89 | "> - 函数文档\n", 90 | "> - 模块\n", 91 | "> - 测试驱动编程\n", 92 | "> - 可执行程序\n", 93 | "\n", 94 | "这些都是你未来写自己的工程时所必须仰仗的基础,马虎不得,疏漏不得。\n", 95 | "\n", 96 | "另外,这一部分与第一部分有一个刻意不同的编排,这一部分的每一章之后,**没有写总结** —— 那个总结需要读者自己动手完成。你需要做的不仅仅是每一个章节的总结,整个第二部分读完之后,还要做针对整个 “深入了解函数”(甚至应该包括第一部分已经读过的关于函数的内容)的总结…… 并且,关于函数,这一章并未完全讲完呢,第三部分还有生成器、迭代器、以及装饰器要补充 —— 因为它们多多少少都涉及到下一部分才能深入的内容,所以,在这一部分就暂时没有涉及。\n", 97 | "\n", 98 | "你要习惯,归纳、总结、整理的工作,从来都不是一次就能完成的,都需要反复多次之后才能彻底完成。必须习惯这种流程 —— 而不是像那些从未自学过的人一样,对这种东西想当然地全不了解。\n", 99 | "\n", 100 | "另外,从现代编程方法论来看,“写作” 部分一上来就从函数入手也的确是 “更正确” 的,因为结构化编程的核心就是拆分任务,把任务拆分到不能再拆分为止 —— 什么时候不能再拆分了呢?就是当一个函数只完成一个功能的时候……" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Next Page" 108 | ] 109 | } 110 | ], 111 | "metadata": { 112 | "kernelspec": { 113 | "display_name": "Python 3", 114 | "language": "python", 115 | "name": "python3" 116 | }, 117 | "language_info": { 118 | "codemirror_mode": { 119 | "name": "ipython", 120 | "version": 3 121 | }, 122 | "file_extension": ".py", 123 | "mimetype": "text/x-python", 124 | "name": "python", 125 | "nbconvert_exporter": "python", 126 | "pygments_lexer": "ipython3", 127 | "version": "3.8.3" 128 | } 129 | }, 130 | "nbformat": 4, 131 | "nbformat_minor": 2 132 | } 133 | -------------------------------------------------------------------------------- /Part.2.E.deliberate-thinking.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 刻意思考" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "随着时间的推移,你会体会到它的威力:\n", 15 | "\n", 16 | "> 刻意思考哪儿需要刻意练习\n", 17 | "\n", 18 | "只不过是一句话而已,却因知道或不知道,竟然会逐渐形成天壤之别的差异,也是神奇。\n", 19 | "\n", 20 | "刻意思考,就是所谓的琢磨。琢磨这事,一旦开始就简单得要死,可无从下手的时候就神秘无比。让我们再看一个 “刻意思考” —— 即,琢磨 —— 的应用领域:\n", 21 | "\n", 22 | "> **这东西能用在哪儿呢?**\n", 23 | "\n" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "很多人学了却没怎么练,有一个很现实的原因 —— 没什么地方用得上。\n", 31 | "\n", 32 | "这也怪我们的应试教育,大学前上 12 年学,“学”(更多是被逼的)的绝大多数东西,只有一个能够切实体会到的用处,考试 —— 中考、高考,以及以它们为目标的无数 “模考”…… 于是,反过来,不管学什么东西,除了考试之外,几乎无法想象其他的用处。\n", 33 | "\n", 34 | "一旦我们启动了对某项技能的自学之后,在那过程中,最具价值的刻意思考就是,时时刻刻琢磨 “这东西能用在哪儿呢?”\n", 35 | "\n", 36 | "比如,当你看到字符串的 Methods 中有一个 `str.zfill()` 的时候,马上就能想到,“嗯!这可以用来批量更名文件……”\n", 37 | "\n", 38 | "![](images/rename-macos.png)\n", 39 | "\n", 40 | "虽然现在的 Mac OS 操作系统里已经有相当不错的批量更名工具内建在 Finder 之中(选中多个文件之后,在右键菜单中能看到 `rename` 命令),但这是近期才加进去的功能,几年前却没有 —— 也就是说,几年前的时候,有人可以用 `str.zfill()` 写个简单的程序完成自己的工作,而另外一些人仅因为操作系统没有提供类似的功能就要么手工做,要么干脆忍着忘了算了……\n", 41 | "\n", 42 | "但更多的时候,需要你花时间去琢磨,才能找到用处。\n", 43 | "\n", 44 | "找到用处,有时候还真挺难的 —— 因为人都一样,容易被自己的眼界所限,放眼望过去,没有用处,自然也就不用了,甚至不用学了,更不用提那就肯定是感觉不用练了……\n", 45 | "\n", 46 | "所以,仔细想想罢 —— 那些在学校里帮老师干活的小朋友们,更多情况下还真不是很多人以为的 “拍马屁”(不排除肯定有哈),只不过是在 “主动找活干”……\n", 47 | "\n", 48 | "**找活干**,是应用所学的最有效方式,有活干,所以就有问题需要解决,所以就有机会反复攻关,在这个过程中,**以用带练**……\n", 49 | "\n", 50 | "所以,很多人在很多事上都想反了。\n", 51 | "\n", 52 | "人们常常取笑那些呼哧呼哧干活的人,笑着说,“能者多劳”,觉得他们有点傻。\n", 53 | "\n", 54 | "这话真的没错。但这么说更准:**劳者多能** —— 你看,都想反了吧?\n", 55 | "\n", 56 | "到最后,一切自学能力差的人,外部的表现都差不多,都起码包括这么一条:眼里没活。他们也不喜欢干活,甚至也没想过,玩乐也是干活(每次逢年过节玩得累死那种)—— 从消耗或者成本的角度来看根本没啥区别 —— 只不过那些通常都是没有产出的活而已。\n", 57 | "\n", 58 | "在最初想不出有什么用处的时候,还可以退而求其次,看看 “别人想出什么用处没有?” —— 比如,我去 Google `best applications of python skill`,在第一个页面我就发现了这么篇文章:“[What exactly can you do with Python? ](https://medium.freecodecamp.org/what-can-you-do-with-python-the-3-main-applications-518db9a68a78)”,翻了一会儿觉得颇有意思……" 59 | ] 60 | }, 61 | { 62 | "cell_type": "markdown", 63 | "metadata": {}, 64 | "source": [ 65 | "再高阶一点的刻意思考(琢磨),无非是在 “这东西能用在哪儿呢?” 这句话里加上一个字而已:\n", 66 | "\n", 67 | "> 这东西**还**能用在哪儿呢?\n", 68 | "\n", 69 | "我觉得这个问题对思维训练的帮助非常深刻 —— 别看只是多了一个字而已。\n", 70 | "\n", 71 | "当我读到在编程的过程中有很多的 “约定” 的时候,就琢磨着:\n", 72 | "\n", 73 | "> * 哦,原来约定如此重要……\n", 74 | "> * 哦,原来竟然有那么多人不重视约定……\n", 75 | "> * 哦,原来就应该直接过滤掉那些不遵守约定的人……\n", 76 | "> —— 那这个原理(东西)还能用在哪儿呢?\n", 77 | "> —— 哦,在生活中也一样,遇到不遵守约定的人或事,直接过滤,不要浪费自己的生命……\n", 78 | "\n", 79 | "学编程真的很有意思,因为这个领域是世界上最聪明的人群之一开辟出来并不断共同努力着发展的,所以,在这个世界里有很多思考方式,琢磨方式,甚至可以干脆称为 “做事哲学” 的东西,可以普遍应用在其它领域,甚至其它任何领域。\n", 80 | "\n", 81 | "比如,在开发方法论中,有一个叫做 [MoSCoW Method](https://en.wikipedia.org/wiki/MoSCoW_method) 的东西,1994 年由 Clegg Dai 在《Case Method Fast-Track: A RAD Approach》一书中提出的 —— 两个 `o` 字母放在那里,是为了能够把这个缩写读出来,发音跟莫斯科一样。\n", 82 | "\n", 83 | "简单说,就是,凡事都可以分为:\n", 84 | "\n", 85 | "> * Must have\n", 86 | "> * Should have\n", 87 | "> * Could have\n", 88 | "> * Won't have\n", 89 | "\n", 90 | "于是,在开发的时候,把所谓的需求打上这 4 个标签中的某一个,以此分类,就很容易剔除掉那些实际上做了还不如不做的功能……\n", 91 | "\n", 92 | "琢磨一下罢,这个东西还可以用在什么地方?\n", 93 | "\n", 94 | "显然,除了编程之外,其他应用领域挺多的,这个原则相当地有启发性……\n", 95 | "\n", 96 | "我写书就是这样的。在准备的过程中 —— 这个过程比绝大多数人想象得长很多 —— 我会罗列所有我能想到的相关话题…… 等我觉得已经再也没有什么可补充的时候,再为这些话题写上几句话构成大纲…… 这时候就会发现很多话题其实应该是同一个话题。如此这般,一次扩张,一次收缩之后,就会进行下一步,应用 MoSCoW 原则,给这些话题打上标签 —— 在这过程中,总是发现很多之前感觉必要的话题,其实可以打上 `Won't have` 的标签,于是,把它们剔除,然后从 `Must have` 开始写起,直到 `Should have`,至于 `Could have` 看时间是否允许,看情况,比如,看有没有最后期限限制……\n", 97 | "\n", 98 | "在写书这事上,我总是给人感觉很快,事实上也是,因为有方法论 —— 但显然,那方法论不是从某一本 “如何写书” 的书里获得的,而是从另外一个看起来完全不相关的领域里习得后琢磨到的……\n", 99 | "\n", 100 | "所谓的 “活学活用”,所谓的 “触类旁通”,也不过如此。" 101 | ] 102 | }, 103 | { 104 | "cell_type": "markdown", 105 | "metadata": {}, 106 | "source": [ 107 | "Next Page" 108 | ] 109 | } 110 | ], 111 | "metadata": { 112 | "kernelspec": { 113 | "display_name": "Python 3", 114 | "language": "python", 115 | "name": "python3" 116 | }, 117 | "language_info": { 118 | "codemirror_mode": { 119 | "name": "ipython", 120 | "version": 3 121 | }, 122 | "file_extension": ".py", 123 | "mimetype": "text/x-python", 124 | "name": "python", 125 | "nbconvert_exporter": "python", 126 | "pygments_lexer": "ipython3", 127 | "version": "3.8.3" 128 | } 129 | }, 130 | "nbformat": 4, 131 | "nbformat_minor": 2 132 | } 133 | -------------------------------------------------------------------------------- /Part.3.A.conquering-difficulties.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 战胜难点" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "无论学什么,都有难点。所谓的 “学习曲线陡峭”,无非就是难点靠前、难点很多、难点貌似很难而已。\n", 15 | "\n", 16 | "然而,相信我,所有的难点,事实上都可以被拆解成更小的单元,而后在逐一突破的时候,就没那么难了。逐一突破全部完成之后,再拼起来重新审视的时候就会发现那所谓的难常常只不过是错觉、幻觉而已 —— 我把它称为**困难幻觉**。\n", 17 | "\n", 18 | "把一切都当作手艺看的好处之一就是心态平和,因为你知道那不靠天分和智商,它靠的是另外几件事:不混时间,刻意思考,以及刻意练习 —— 其实吧,老祖宗早就有总结:\n", 19 | "\n", 20 | "> 天下无难事,只怕**有心人**……\n", 21 | "\n", 22 | "大家都是人,咋可能没 “心” 呢?\n", 23 | "\n", 24 | "想成为有心人,其实无非就是学会拆解之后逐一突破,就这么简单。" 25 | ] 26 | }, 27 | { 28 | "cell_type": "markdown", 29 | "metadata": {}, 30 | "source": [ 31 | "第三部分所用的例子依然非常简单 —— 这当然是作者的刻意;但是,所涉及的话题都是被认为 “很难很难”、“很不容易理解”、“初学者就没必要学那些了” 之类的话题:\n", 32 | "\n", 33 | "> * 类,以及面向对象编程(Class,OOP)\n", 34 | "> * 迭代器、生成器、装饰器(Iterators、Generators、Decorators)\n", 35 | "> * 正则表达式(Regular Expressions)\n", 36 | "> * 巴科斯-诺尔范式(Backus Normal Form)\n", 37 | "\n", 38 | "尤其是最后一个,巴科斯-诺尔范式,几乎所有的编程入门书籍都不会提到……\n", 39 | "\n", 40 | "然而,这些内容,在我设计《自学是门手艺》内容的过程中,是被当作 `Must have`,而不是 `Should have`,当然更不是 `Could have` 或者 `Won't have` 的。\n", 41 | "\n", 42 | "它们属于 `Must have` 的原因也很简单:\n", 43 | "\n", 44 | "> 无论学什么都一样,难的部分不学会,就等于整个没学。\n", 45 | "\n", 46 | "—— 仅因为不够全面。\n", 47 | "\n", 48 | "有什么必要干前功尽弃的事情呢?要么干脆别学算了,何必把自己搞成一个半吊子?—— 可惜,这偏偏是绝大多数人的习惯,学什么都一样,容易的部分糊弄糊弄,困难的部分直接回避…… 其实,所有焦虑,都是这样在许多年前被埋下,在许多年后生根发芽、茂盛发达的 —— 你想想看是不是如此?" 49 | ] 50 | }, 51 | { 52 | "cell_type": "markdown", 53 | "metadata": {}, 54 | "source": [ 55 | "虽然别人认为难,你刚开始也会有这样的错觉,但只要你开始施展 “读不懂也要读完,读完之后再读很多遍” 的手段,并且还 “不断自己动手归纳总结整理”,你就会 “发现”,其实没什么大不了的,甚至你会有错觉:\n", 56 | "\n", 57 | "> “突然” 之间一切都明了了!\n", 58 | "\n", 59 | "那个 “突然”,其实就是阿基米德的 [Eureka](https://en.wikipedia.org/wiki/Eureka_effect),那个他从澡堂里冲出来大喊大叫的词汇。\n", 60 | "\n", 61 | "![](images/archimedes-eureka.png)\n", 62 | "\n", 63 | "其实吧,泡澡和冥想,还真是最容易产生 Eureka 状态的两种活动。原理在于,泡澡和打坐的时候,大脑都极其放松,乃至于原本相互之间并无联系的脑神经突触之间突然产生相互关联;而那结果就是日常生活中所描述的 “融会贯通”,于是,突然之间,Eureka!\n", 64 | "\n", 65 | "自学者总是感觉幸福度很高,就是这个原因。日常中因为自学,所以总是遇到更多的困难。又因为这些东西不过是手艺,没什么可能终其一生也解决不了,恰恰相反,都是假以时日必然解决的 “困难”…… 于是,自学者恰恰因为遇到的 “困难” 多,所以才有更多遇到 “Eureka” 的可能性,那种幸福,还真的难以表述,即便表述清楚了,身边的人也难以理解,因为自学者就是很少很少。" 66 | ] 67 | }, 68 | { 69 | "cell_type": "markdown", 70 | "metadata": {}, 71 | "source": [ 72 | "对很多人来说,阅读的难点在于起初的时候它总是显得异常枯燥。\n", 73 | "\n", 74 | "刚识字、刚上学的时候,由于理解能力有限,又由于年龄的关系于是耐心有限,所以,那时需要老师耐心陪伴、悉心引导。这就好像小朋友刚出生的时候,没有牙齿,所以只能喝奶差不多…… 然而,到了一定程度之后一定要断奶,是不是?可绝大多数人的实际情况却是,小学的时候爱上了 “奶嘴”(有人带着阅读),而后一生没有奶嘴就吃不下任何东西。\n", 75 | "\n", 76 | "他们必须去 “上课”,需要有人给他们讲书。不仅如此,讲得 “不生动”、“不幽默” 还不行;就算那职业提供奶嘴的人(这是非常令人遗憾的真相:很多的时候,所谓的 “老师” 本质上只不过就是奶妈而已)帅气漂亮、生动幽默、尽职尽力…… 最终还是一样的结果 —— 绝大多数人依然没有完整掌握所有应该掌握的细节。\n", 77 | "\n", 78 | "开始 “自学” 的活动,本质上来看,和**断奶**其实是一回事。\n", 79 | "\n", 80 | "> * 知识就是知识,它没有任何义务去具备幽默生动的属性;\n", 81 | "> * 手艺就是手艺,它没有任何义务去具备有趣欢乐的属性。\n", 82 | "\n", 83 | "幽默与生动,是要自己去扮演的角色;有趣与欢乐,是要自己去挖掘的幸福 —— 它们从来都并不自动包含在知识和手艺之中。只有当它们被 “有心人” 掌握、被 “有心人” 应用、甚至被 “有心人” 拿去创造的时候,也只有 “有心人” 才能体会到那幽默与生动、那有趣与欢乐。\n", 84 | "\n", 85 | "所以,有自学能力的人,不怕枯燥 —— 因为那本来就理应是枯燥的。这就好像人生本无意义,有意义的人生都是自己活出来的一样,有意义的知识都是自己用出来的 —— 对不用它的人,用不上它的人来说,只能也只剩下无法容忍的枯燥。\n", 86 | "\n", 87 | "能够**耐心**读完那么多在别人看来 “极度枯燥” 的资料,是自学者的擅长。可那在别人看来 “无以伦比” 的耐心,究竟是哪儿来的呢?如何造就的呢?没断奶的人想象不出来。其实也很简单,首先,平静地接受了它枯燥的本质;其次,就是经过多次实践已然明白,无论多枯燥,总能读完;无论多难,多读几遍总能读懂…… 于是,到最后,**只不过是习惯了而已。**" 88 | ] 89 | }, 90 | { 91 | "cell_type": "markdown", 92 | "metadata": {}, 93 | "source": [ 94 | "第三部分关于编程的内容过后,还有若干关于自学的内容。\n", 95 | "\n", 96 | "在反复阅读编程部分突破难点的过程之中、过程之后,你会对那些关于自学的内容有更深更生动的认识。很多道理过去你都知道是对的,只不过因为没有遇到过生动的例子 —— 主要是没遇到过能让自己感到生动的例子 —— 于是你就一直没有重视起来,于是,就还是那句话,那一点点的差异,造成了后来那么大的差距。\n", 97 | "\n", 98 | "然而,既然知道了真相的你,以后就再也没办法蒙蔽自己了 —— 这就是收获,这就是进步。" 99 | ] 100 | }, 101 | { 102 | "cell_type": "markdown", 103 | "metadata": {}, 104 | "source": [ 105 | "Next Page" 106 | ] 107 | } 108 | ], 109 | "metadata": { 110 | "kernelspec": { 111 | "display_name": "Python 3", 112 | "language": "python", 113 | "name": "python3" 114 | }, 115 | "language_info": { 116 | "codemirror_mode": { 117 | "name": "ipython", 118 | "version": 3 119 | }, 120 | "file_extension": ".py", 121 | "mimetype": "text/x-python", 122 | "name": "python", 123 | "nbconvert_exporter": "python", 124 | "pygments_lexer": "ipython3", 125 | "version": "3.8.3" 126 | } 127 | }, 128 | "nbformat": 4, 129 | "nbformat_minor": 2 130 | } 131 | -------------------------------------------------------------------------------- /Part.3.G.the-golden-age-and-google.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 这是自学者的黄金时代" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "历史上,自学者从未像今天这样幸福。\n", 15 | "\n", 16 | "以前不是这样的。比如,几乎每个中国人从小就听说过无数次那种 “为了拜师学艺一跪就几天甚至几个月也不一定被收下” 的故事。\n", 17 | "\n", 18 | "在古代,拜师学艺的确是很难的事情。首先,真正的好老师确实难寻;其次,高手也没空当老师;再次,就算是肯收徒授艺的老师也总是时间精力极其有限…… 更为重要的是,那时候想自学也真不行 —— 根本就没有什么称得上是文献的东西可供阅读或检索,很多重要信息甚至干脆只存在于某些人的脑中,就算它们被落实成了文献,也相当有限,且散落深藏在各处 —— 就算凑齐了,也没有 [Google](https://www.google.com/ncr)!\n", 19 | "\n", 20 | "对,最关键的是那时候没有 Google……\n", 21 | "\n", 22 | "今天的互联网,已经不再是二十几年前刚出现的那样 “激进而简陋” 的东西了。经过多年的发展,互联网上的内容已经构成了真正意义上的 “全球唯一通用图书馆” —— 而针对它可用的检索工具中最好的,当然是 Google。\n", 23 | "\n", 24 | "于是,今天,自学者在真正的意义上身处于一个黄金时代 —— **没有什么是不能自学的**。注意措辞,在这句话前面甚至根本不用加上 “几乎” 这样的限定以示准确 —— 你想学什么,就能学什么,而不是 “只有先拜师才能开始学艺”。\n", 25 | "\n", 26 | "今天的你,想学什么就去问 Google;在学习中遇到什么问题,就直接问 Google —— 直接问它,通常总是比向某个人提问有效率得多。Google 就是这样,越用越离不开它……\n", 27 | "\n", 28 | "其实很多人并不真的懂如何用好 Google 的,可是连这个它也能解决,因为你可以直接问它:\n", 29 | "\n", 30 | "> [How to use google effectively](https://www.google.com/search?q=How+to+use+google+effectively)\n", 31 | "\n", 32 | "经过多年的发展,Google 的使用体验越来越好,2019 年的今天,你搜索以上语句返回的页面里,Google 甚至在众多搜索结果中选了一条它 “认为” 是 “最佳” 的搜索结果:\n", 33 | "\n", 34 | "![google-how-effectively](images/google-how-effectively.png)\n", 35 | "\n", 36 | "[lifehack.com 上的这篇文章](https://www.lifehack.org/articles/technology/20-tips-use-google-search-efficiently.html)也的的确确值得细读 —— 读过且真正理解之后,不夸张地讲,你的 “搜索技能” 已经足够灭掉整个人类当前活跃群体中的 99% 了…… 这个说法真的完全没有夸张,绝大多数人就是不会在搜索的过程中使用那些符号的,比如 `-` `*` `~` `@` `#` `:` `\"` `..` —— 还有很多其它技巧…… 话说,你在 Google 上用过 `Time *place*` 吗?\n", 37 | "\n", 38 | "已经掌握了正则表达式以及 glob 的你,学习一下如何使用这种符号,实在是太小菜一碟了 —— 然而,这么简单的东西所能带来的未来收益是非常惊人的,不信走着瞧。\n", 39 | "\n", 40 | "可实际上,还是得应用我们之前说过的原则:\n", 41 | "\n", 42 | "> 首选查询,肯定是官方文档。\n", 43 | "\n", 44 | "这么做的重要理由之一,是为了让你少受 “二手知识” 的蒙蔽和误导。这里有一个绝佳的例子让你理解二手知识的局限性:[我写过的一本 “书”,发布在网上](https://github.com/xiaolai/ji) —— 这本 “书” 的另外一个 “神” 之处,在于它能让你 “顿悟” 阅读的力量,不管你是男生还是女生…… 若是这个链接错过了,你竟然会错过整个生活!\n", 45 | "\n", 46 | "Google Search 的官方文档在这里:\n", 47 | "\n", 48 | "> https://support.google.com/websearch\n", 49 | "\n", 50 | "Google 还有更为强大的工具给你使用,叫做 Google Custom Search,官方文档在这里:\n", 51 | "\n", 52 | "> https://support.google.com/customsearch/\n", 53 | "\n", 54 | "对编程工作来说,Google 当然格外地更为重要 —— 互联网上积累的最多最专业的信息,当然是计算机相关信息。所以,当你遇到什么错误提示的时候,不仅要问 Google,还要优先问问 [Stackoverflow](https://stackoverflow.com) —— 连 Google 自己都这么干。在 [colab.research.google.com](https://colab.research.google.com)(Google 为它的 TensorFlow 服务搭建的 Jupyterlab 环境)上,如果你运行什么代码出错了的话,那么,出错信息下面会出现一个按钮,上面写着:`SEARCH STACK OVERFLOW`,点击它就直接给你 [Stackoverflow](https://stackoverflow.com) 上的搜索结果…… 真够意思!\n", 55 | "\n", 56 | "![google-stackoverflow](images/google-stackoverflow.png)\n", 57 | "\n", 58 | "[Google](https://google.com)、[Stackoverflow](https://stackoverflow.com)、[Wikipedia](https://en.wikipedia.org)、[Youtube](https://youtube.com),这些都是你经常要去搜索的好地方。\n", 59 | "\n", 60 | "二十年前,Google 刚出现的时候,谁能想象它今天这个样子呢?以下是 1998 年 11 月 11 日 http://google.com 这个网址的截图:\n", 61 | "\n", 62 | "![google-homepage-1998](images/google-homepage-1998.png)\n", 63 | "\n", 64 | "当时,网站还没有正式上线,第一个链接是一个原型设计,用一个二级域名发布在斯坦福的网站上:http://google.stanford.edu/:\n", 65 | "\n", 66 | "![google-prototype-1998](images/google-prototype-1998.png)\n", 67 | "\n", 68 | "那个时候,Google 还要向外人强调一下,他们已经有 2500 万页面可供检索!\n", 69 | "\n", 70 | "事实上,到了 2008 年,Google 公告称,可供检索页面已经超过一万亿(One Trillion),到了 2016 年年底,这个数字已经超过 130 万亿……\n", 71 | "\n", 72 | "换个角度看,这个数字同时也是互联网上信息的积累 —— 世界上再没有比互联网更大更全的 “书” 了。并且,由于 Google 的存在,互联网这本大书,是可检索的!\n", 73 | "\n", 74 | "于是,**有事先问 Google** 就成了自学者的必备修养。\n", 75 | "\n", 76 | "> 能 Google 出答案的问题,就不需要去麻烦别人。\n", 77 | "\n", 78 | "这也是一个自学者的基本素养。\n", 79 | "\n", 80 | "偶尔,也确实会遇到 Google 了很久,就是没有找到答案的情况…… 这样的时候,你可能需要想办法 “问人” 了。然而,最靠谱的通常并不见得是 “身边的人”,而是互联网上各种垂直社区里的其他用户……\n", 81 | "\n", 82 | "向人问,也是有学问的 —— 很多人张口就问,结果呢?结果没人理。为什么呢?\n", 83 | "\n", 84 | "作为一个有素养的自学者,有一篇文章必须精读:\n", 85 | "\n", 86 | "> [How To Ask Questions The Smart Way](https://github.com/selfteaching/How-To-Ask-Questions-The-Smart-Way)\n", 87 | "\n", 88 | "这是大神 Eric S. Raymond 和 Rick Moen 于 2001 年在网上发布的文章,被人们奉为经典;迄今为止经历了很多次的修订,最后一次是在 2014 年,`Revision 3.10` —— 前后被翻译成了许多种语言。\n", 89 | "\n", 90 | "**不认真使用 Google,你就错过了整个人类历史上自学者最黄金的时代。**" 91 | ] 92 | }, 93 | { 94 | "cell_type": "markdown", 95 | "metadata": {}, 96 | "source": [ 97 | "Next Page" 98 | ] 99 | } 100 | ], 101 | "metadata": { 102 | "kernelspec": { 103 | "display_name": "Python 3", 104 | "language": "python", 105 | "name": "python3" 106 | }, 107 | "language_info": { 108 | "codemirror_mode": { 109 | "name": "ipython", 110 | "version": 3 111 | }, 112 | "file_extension": ".py", 113 | "mimetype": "text/x-python", 114 | "name": "python", 115 | "nbconvert_exporter": "python", 116 | "pygments_lexer": "ipython3", 117 | "version": "3.8.3" 118 | } 119 | }, 120 | "nbformat": 4, 121 | "nbformat_minor": 2 122 | } 123 | -------------------------------------------------------------------------------- /Part.3.H.prevent-focus-drifting.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 避免注意力漂移" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "**注意力漂移**,是我杜撰的一个词,用来作为 “注意力集中” 的反义词 —— 因为更多的时候,我们并不是 “注意力不集中”,而是…… 而是更令人恼火的一个现象:\n", 15 | "\n", 16 | "> “注意力所集中的焦点总是不断被自己偷偷换掉……”\n", 17 | "\n", 18 | "比如,你本来只不过就想着去 Google 一个编程错误信息的解读,结果不知道怎么就 “注意到” 了另外一个东西,比如,“某编辑器的皮肤”,然后你就 “顺手” 把它下载下来,然后 “很自然地顺手把它装上”,而后又看了看,觉得有点必要于是 “顺手做了点定制”…… 然后欣赏了一会儿,并自我得意一番之后 “突然发现” 自己还没有解决两小时之前要解决的问题!\n", 19 | "\n", 20 | "说这种现象 “令人恼火”,是因为那注意力所集中的焦点,是被**自己**偷偷换掉的!" 21 | ] 22 | }, 23 | { 24 | "cell_type": "markdown", 25 | "metadata": {}, 26 | "source": [ 27 | "好奇心越重的人,越是容易被注意力漂移所拖累。\n", 28 | "\n", 29 | "好奇心是好东西,而且是必须认真呵护的东西 —— 几乎最重要、最强劲的自学动力,都混合着好奇心出现并持续。\n", 30 | "\n", 31 | "在我成长的那个年代里,很多孩子本来是可以成为自学专家的,结果,99.99% 都被父母给毁了 —— 而且还是不经意地毁的。那些父母毁掉自己孩子的方法简单直接又粗暴、且毫不犹豫。\n", 32 | "\n", 33 | "刚开始图好玩,小孩子问啥都回答…… 当然,最初的时候,小孩子问的问题也很容易回答;就算不容易,也很容易糊弄过去。没多久,父母就开始应付不过来了,一方面自己也没那么多耐心了,另外一方面是更为严重的问题 —— 自己的脑力不够。再加上那时候也没有 Google,所以,父母的反应惊人地一致:“去去去,赶紧睡觉!怎么就你事这么多?!”\n", 34 | "\n", 35 | "一个个小朋友就这样被毁掉了,他们的好奇心就这样成了他们自己要主动避免的东西 —— 否则就会挨骂,谁愿意动不动就被一通数落呢?\n", 36 | "\n", 37 | "好奇心是驱动一个人不断进步的最重要动力之一。所以必须不断呵护,呵护到老才对。\n", 38 | "\n", 39 | "然而,就是这个如此金贵的东西,也会成为拖累;而且,若是真的被它拖累,那么最终真的会感觉非常遗憾,被好东西拖累 —— 太可惜了。\n", 40 | "\n", 41 | "刚才所描述的,还只不过是两个小时而已的 “损失”。事实上,被注意力漂移所拖累的人,损失肯定远不止如此。在做 “工程” 或者 “项目” 的时候 —— 尤其是那种非实物类的工程或项目,比如,写个书,写个软件之类的 —— 注意力漂移导致的结果就是:\n", 42 | "\n", 43 | "> 时间不断流逝,可是工程却永远没有结果。\n", 44 | "\n", 45 | "这种损失,完全是任何正常人都没办法承受的…… 这话其实并不准,因为事实上据我观察,绝大多数人受到这种拖累的结果,自己其实无法想象 —— 因为永远没有完成过什么项目,永远没有完成过什么工程,又如何知道自己损失的究竟是什么呢?" 46 | ] 47 | }, 48 | { 49 | "cell_type": "markdown", 50 | "metadata": {}, 51 | "source": [ 52 | "到今天为止,我自己依然还是个需要不断与 “注意力漂移” 争斗的人 —— 许多年前,我注意到这个现象的时候,经过思考,就接受了一个事实:\n", 53 | "\n", 54 | "> 注意力漂移不是能杜绝的现象,但必须在关键时刻有所应对……\n", 55 | "\n", 56 | "如果当年的我没认真想过这事,没思索出对策,那么后来的我也不可能写那么多书,转行那么多次,自学那么多大大小小的技能…… 当然,各位读者也完全看不到现在正在阅读的文字 —— 因为它们不可能被完整地写出来,甚至干脆就不应该存在。\n", 57 | "\n", 58 | "在罗列并比较众多策略之后,我选了一个看起来最不相干,却最本质的策略:\n", 59 | "\n", 60 | "> **把 “全面完整” 放到最高优先级。**\n", 61 | "\n", 62 | "而后,这些年全靠这个策略挺了过来……\n", 63 | "\n", 64 | "当我想做什么事的时候,或者想学什么东西的时候,我会投入一定的时间去琢磨,这个事或者这个东西,要做得全面完整,或者要学得全面完整,那都应该做什么呢?在思考如此严肃的问题的时候,我还是习惯用纸和笔,写写画画 —— 迄今为止没有找到合适的电子设备和软件替代。\n", 65 | "\n", 66 | "我买笔记本,不是为了记笔记的,因为记笔记这个东西,实在是在电脑上做更方便,许多年前开始就是如此了。我的笔记本主要用来做一件事:\n", 67 | "\n", 68 | "> 罗列整理那些为了做到 “全面完整” 而必须优先做的事。\n", 69 | "\n", 70 | "用列表也好、或者用图表也罢,反正都是要不断整理修订的,而它的存在,给了我一个优先级:\n", 71 | "\n", 72 | "> 除了这上面罗列的这些东西之外,在当前时间段,别的都不如它们重要。\n", 73 | "\n", 74 | "一旦发现自己的注意力没有集中在这上面的关键之时,一旦发现自己的注意力已经漂移到其它当前并不重要的事项上,就马上纠正。\n", 75 | "\n", 76 | "谁都知道应该先做重要且紧急的事情,可问题在于,如何判断 “是否重要” 呢?**全面完整**这四个字就会给我指引。" 77 | ] 78 | }, 79 | { 80 | "cell_type": "markdown", 81 | "metadata": {}, 82 | "source": [ 83 | "一方面,是用全面完整来保持自己对重要事情的关注,另外一方面,还需要提高对抗**不相关完美诱惑**的能力。十年前,我写《[把时间当作朋友](https://github.com/xiaolai/time-as-a-friend)》的时候,还把这东西叫做 “脆弱的完美主义倾向”,现在我已经把这个概念升级了 —— 因为更准确地讲,那不是 “完美主义者的脆弱”,那是 “能力不及格者” 的 “轻重不分”。" 84 | ] 85 | }, 86 | { 87 | "cell_type": "markdown", 88 | "metadata": {}, 89 | "source": [ 90 | "早些年,我跟很多人一样痴迷于电脑这个东西,也跟很多人那样,用 Windows 惯出来了坏毛病 —— 动不动就重装系统…… 重装系统很浪费时间的,但那时也不知道为什么总是忍不住去干那事,哪怕有些小毛病,马上就受不了,弄的好像重装一个干净的操作系统会让自己的世界焕然一新一样。\n", 91 | "\n", 92 | "再后来就明白了,这绝对就是**自己的毛病 —— 做事不分轻重**。\n", 93 | "\n", 94 | "说实话,这也不是自己想明白的 —— 我没那么聪明。是因为遇到了一个高人。他的电脑桌面上,乱七八糟摆满了各种图标,从不整理。我问他这不影响效率吗?他说,明明有搜索你不用,到底是谁效率低下?我被问愣了,无言以对。\n", 95 | "\n", 96 | "我又发现他根本没有装杀毒软件…… 我问为什么?他说,“养几个虫子玩玩也没什么不好……” 不过,他转念又告诉了我他的思考。他说,只要平时习惯好,病毒进来了也没啥可偷的,但更为关键的是,他用电脑是干活的,而不是干杀毒的活的…… 脑子如此清楚,让我自愧不如。\n", 97 | "\n", 98 | "但学到了。\n", 99 | "\n", 100 | "虽然我还是做不到桌面上图标很乱,虽然我是因为改用了 Mac OS,所以不装杀毒软件,但注意力要放到应该放的地方,这事我记住了,牢牢记住,从此之后许多年,从未忘过。每次发现自己轻重不分的时候,就会想起他,然后就改过自新。" 101 | ] 102 | } 103 | ], 104 | "metadata": { 105 | "kernelspec": { 106 | "display_name": "Python 3", 107 | "language": "python", 108 | "name": "python3" 109 | }, 110 | "language_info": { 111 | "codemirror_mode": { 112 | "name": "ipython", 113 | "version": 3 114 | }, 115 | "file_extension": ".py", 116 | "mimetype": "text/x-python", 117 | "name": "python", 118 | "nbconvert_exporter": "python", 119 | "pygments_lexer": "ipython3", 120 | "version": "3.8.3" 121 | } 122 | }, 123 | "nbformat": 4, 124 | "nbformat_minor": 2 125 | } 126 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # the-craft-of-selfteaching 2 | 3 | > One has no future if one couldn't teach themself[1]. 4 | 5 | # 自学是门手艺 6 | 7 | > 没有自学能力的人没有未来 8 | 9 | **作者:李笑来** 10 | 11 | 特别感谢**霍炬**([@virushuo](https://github.com/virushuo))、**洪强宁**([@hongqn](https://github.com/hongqn)) 两位良师诤友在此书写作过程中给予我的巨大帮助! 12 | 13 | ```python 14 | # pseudo-code of selfteaching in Python 15 | 16 | def teach_yourself(anything): 17 | while not create(): 18 | learn() 19 | practice() 20 | return teach_yourself(another) 21 | 22 | teach_yourself(coding) 23 | ``` 24 | 25 | 请先行阅读 [T-appendix.jupyter-installation-and-setup](T-appendix.jupyter-installation-and-setup.ipynb) 以便在本地安装 [Jupyterlab](https://github.com/jupyterlab/jupyterlab) 而后就能用更好的体验阅读本书。 26 | 27 | 有兴趣帮忙的朋友,请先行阅读 [如何使用 Pull Request 为这本书校对](02.proof-of-work.ipynb)。 28 | 29 | 2019 年 3 月 23 日,新增 Markdown 版本: 30 | 31 | > https://github.com/selfteaching/the-craft-of-selfteaching/tree/master/markdown 32 | 33 | ### 目录 34 | 35 | > - [01.preface(**前言**)](01.preface.ipynb) 36 | > - [02.proof-of-work(**如何证明你真的读过这本书?**)](02.proof-of-work.ipynb) 37 | > - [Part.1.A.better.teachyourself(**为什么一定要掌握自学能力?**)](Part.1.A.better.teachyourself.ipynb) 38 | > - [Part.1.B.why.start.from.learning.coding(**为什么把编程当作自学的入口?**)](Part.1.B.why.start.from.learning.coding.ipynb) 39 | > - [Part.1.C.must.learn.sth.only.by.reading(**只靠阅读习得新技能**)](Part.1.C.must.learn.sth.only.by.reading.ipynb) 40 | > - [Part.1.D.preparation.for.reading(**开始阅读前的一些准备**)](Part.1.D.preparation.for.reading.ipynb) 41 | > - [Part.1.E.1.entrance(**入口**)](Part.1.E.1.entrance.ipynb) 42 | > - [Part.1.E.2.values-and-their-operators(**值及其相应的运算**)](Part.1.E.2.values-and-their-operators.ipynb) 43 | > - [Part.1.E.3.controlflow(**流程控制**)](Part.1.E.3.controlflow.ipynb) 44 | > - [Part.1.E.4.functions(**函数**)](Part.1.E.4.functions.ipynb) 45 | > - [Part.1.E.5.strings(**字符串**)](Part.1.E.5.strings.ipynb) 46 | > - [Part.1.E.6.containers(**数据容器**)](Part.1.E.6.containers.ipynb) 47 | > - [Part.1.E.7.files(**文件**)](Part.1.E.7.files.ipynb) 48 | > - [Part.1.F.deal-with-forward-references(**如何从容应对含有过多 “过早引用” 的知识?**)](Part.1.F.deal-with-forward-references.ipynb) 49 | > - [Part.1.G.The-Python-Tutorial-local(**官方教程:The Python Tutorial**)](Part.1.G.The-Python-Tutorial-local.ipynb) 50 | > - [Part.2.A.clumsy-and-patience(**笨拙与耐心**)](Part.2.A.clumsy-and-patience.ipynb) 51 | > - [Part.2.B.deliberate-practicing(**刻意练习**)](Part.2.B.deliberate-practicing.ipynb) 52 | > - [Part.2.C.why-start-from-writing-functions(**为什么从函数开始?**)](Part.2.C.why-start-from-writing-functions.ipynb) 53 | > - [Part.2.D.1-args(**关于参数(上)**)](Part.2.D.1-args.ipynb) 54 | > - [Part.2.D.2-aargs(**关于参数(下)**)](Part.2.D.2-aargs.ipynb) 55 | > - [Part.2.D.3-lambda(**化名与匿名**)](Part.2.D.3-lambda.ipynb) 56 | > - [Part.2.D.4-recursion(**递归函数**)](Part.2.D.4-recursion.ipynb) 57 | > - [Part.2.D.5-docstrings(**函数的文档**)](Part.2.D.5-docstrings.ipynb) 58 | > - [Part.2.D.6-modules(**保存到文件的函数**)](Part.2.D.6-modules.ipynb) 59 | > - [Part.2.D.7-tdd(**测试驱动的开发**)](Part.2.D.7-tdd.ipynb) 60 | > - [Part.2.D.8-main(**可执行的 Python 文件**)](Part.2.D.8-main.ipynb) 61 | > - [Part.2.E.deliberate-thinking(**刻意思考**)](Part.2.E.deliberate-thinking.ipynb) 62 | > - [Part.3.A.conquering-difficulties(**战胜难点**)](Part.3.A.conquering-difficulties.ipynb) 63 | > - [Part.3.B.1.classes-1(**类 —— 面向对象编程**)](Part.3.B.1.classes-1.ipynb) 64 | > - [Part.3.B.2.classes-2(**类 —— Python 的实现**)](Part.3.B.2.classes-2.ipynb) 65 | > - [Part.3.B.3.decorator-iterator-generator(**函数工具**)](Part.3.B.3.decorator-iterator-generator.ipynb) 66 | > - [Part.3.B.4.regex(**正则表达式**)](Part.3.B.4.regex.ipynb) 67 | > - [Part.3.B.5.bnf-ebnf-pebnf(**BNF 以及 EBNF**)](Part.3.B.5.bnf-ebnf-pebnf.ipynb) 68 | > - [Part.3.C.breaking-good-and-bad(**拆解**)](Part.3.C.breaking-good-and-bad.ipynb) 69 | > - [Part.3.D.indispensable-illusion(**刚需幻觉**)](Part.3.D.indispensable-illusion.ipynb) 70 | > - [Part.3.E.to-be-thorough(**全面 —— 自学的境界**)](Part.3.E.to-be-thorough.ipynb) 71 | > - [Part.3.F.social-selfteaching(**自学者的社交**)](Part.3.F.social-selfteaching.ipynb) 72 | > - [Part.3.G.the-golden-age-and-google(**这是自学者的黄金时代**)](Part.3.G.the-golden-age-and-google.ipynb) 73 | > - [Part.3.H.prevent-focus-drifting(**避免注意力漂移**)](Part.3.H.prevent-focus-drifting.ipynb) 74 | > - [Q.good-communiation(**如何成为优秀沟通者**)](Q.good-communication.ipynb) 75 | > - [R.finale(**自学者的终点**)](R.finale.ipynb) 76 | > - [S.whats-next(**下一步干什么?**)](S.whats-next.ipynb) 77 | > - [T-appendix.editor.vscode(**Visual Studio Code 的安装与配置**)](T-appendix.editor.vscode.ipynb) 78 | > - [T-appendix.git-introduction(**Git 简介**)](T-appendix.git-introduction.ipynb) 79 | > - [T-appendix.jupyter-installation-and-setup(**Jupyterlab 的安装与配置**)](T-appendix.jupyter-installation-and-setup.ipynb) 80 | > - [T-appendix.symbols(**这些符号都代表什么?**)](T-appendix.symbols.ipynb) 81 | 82 | 83 | 本书的版权协议为 [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)。 84 | 85 | ![CC-BY-NC-ND](images/CC-BY-NC-ND.png?raw=true) 86 | 87 | ----- 88 | **脚注** 89 | 90 | [1]:['Themselves' or 'themself'? -- Oxford Dictionary](https://en.oxforddictionaries.com/usage/themselves-or-themself) 91 | 92 | ↑Back to Content↑ 93 | -------------------------------------------------------------------------------- /S.whats-next.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 下一步干什么?" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "理论上,下一步你的选择很多。自学是门手艺,你可以用它去学任何你想要掌握的其它手艺。如果,你有意在编程这个领域继续深入,那么,以下就是一些不错的线索。" 15 | ] 16 | }, 17 | { 18 | "cell_type": "markdown", 19 | "metadata": {}, 20 | "source": [ 21 | "当然,最先应当做的是,去检查一下自己的 “突击” 的结果,去 Pythonbasics.org 做做练习:\n", 22 | "\n", 23 | "> https://pythonbasics.org/Exercises/\n", 24 | "\n", 25 | "除了我在这里介绍的之外,请移步 The Hitchhiker's Guide to Python,它更为全面:\n", 26 | "\n", 27 | "> https://docs.python-guide.org/" 28 | ] 29 | }, 30 | { 31 | "cell_type": "markdown", 32 | "metadata": {}, 33 | "source": [ 34 | "## Python 必读书籍" 35 | ] 36 | }, 37 | { 38 | "cell_type": "markdown", 39 | "metadata": {}, 40 | "source": [ 41 | "无论学什么,一本书肯定不够,以下是学习 Python 的基本必读书籍:\n", 42 | "\n", 43 | "> * [The Python Tutorial](https://docs.python.org/3/tutorial/)\n", 44 | "> * [The Hitchhiker's Guide to Python!](https://docs.python-guide.org/)\n", 45 | "> * [Think Python: How to think like a computer scientist](http://greenteapress.com/wp/think-python-2e/)\n", 46 | "> * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com)\n", 47 | "> * [Effective Python](https://effectivepython.com)\n", 48 | "> * [Python Cookbook](https://www.amazon.com/Python-Cookbook-Recipes-Mastering-ebook/dp/B00DQV4GGY)\n", 49 | "> * [Fluent Python](https://www.amazon.com/Fluent-Python-Concise-Effective-Programming-ebook/dp/B0131L3PW4)\n", 50 | "> * [Problem Solving with Algorithms and Data Structures using Python](http://interactivepython.org/runestone/static/pythonds/index.html)\n", 51 | "> * [Mastering Object-oriented Python - Transform Your Approach to Python Programming](https://www.amazon.com/dp/B00JVQ14UO/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)\n", 52 | "\n", 53 | "更多 Python 书籍:\n", 54 | "\n", 55 | "> https://pythonbooks.revolunet.com\n", 56 | "\n", 57 | "千万别觉得多,只要真的全面掌握,后面再学别的,速度上都会因此快出很多很多……" 58 | ] 59 | }, 60 | { 61 | "cell_type": "markdown", 62 | "metadata": {}, 63 | "source": [ 64 | "## Python Cheatsheet" 65 | ] 66 | }, 67 | { 68 | "cell_type": "markdown", 69 | "metadata": {}, 70 | "source": [ 71 | "你已经知道了,这种东西,肯定是自己整理的才对自己真的很有用…… 不过,你也可以把别人整理的东西当作 “用来检查自己是否有所遗漏” 的工具。\n", 72 | "\n", 73 | "网上有无数 Python Cheatsheets,以下是 3 个我个人认为相当不错的:\n", 74 | "\n", 75 | "> * [Comprehensive Python Cheatsheet](https://gto76.github.io/python-cheatsheet/)\n", 76 | "> * [Python Crash Course - Cheat Sheets](https://github.com/ehmatthes/pcc/tree/master/cheat_sheets)\n", 77 | "> * [Pysheeet](https://www.pythonsheets.com/)" 78 | ] 79 | }, 80 | { 81 | "cell_type": "markdown", 82 | "metadata": {}, 83 | "source": [ 84 | "## Awesome Python" 85 | ] 86 | }, 87 | { 88 | "cell_type": "markdown", 89 | "metadata": {}, 90 | "source": [ 91 | "Github 上的 “居民” 现在已经养成了一个惯例,无论什么好东西,他们都会为其制作一个 “Awesome ...” 的页面,在里面齐心协力搜集相关资源。比如,你想学 Golang,那你去 Google 搜索 [`Awesome Go`](https://www.google.com/search?q=awesome+go),一定会给你指向到一个 Github 上的 “Awesome Go” 的页面……\n", 92 | "\n", 93 | "以下是 Awesome Python 的链接:\n", 94 | "\n", 95 | "> https://github.com/vinta/awesome-python" 96 | ] 97 | }, 98 | { 99 | "cell_type": "markdown", 100 | "metadata": {}, 101 | "source": [ 102 | "## CS 专业的人都在学什么?" 103 | ] 104 | }, 105 | { 106 | "cell_type": "markdown", 107 | "metadata": {}, 108 | "source": [ 109 | "如果你真有兴趣把这门手艺学精,不妨看看 Computer Science 专业的人都在学什么……\n", 110 | "\n", 111 | "下面这个链接值得认真阅读:\n", 112 | "\n", 113 | "> http://matt.might.net/articles/what-cs-majors-should-know/" 114 | ] 115 | }, 116 | { 117 | "cell_type": "markdown", 118 | "metadata": {}, 119 | "source": [ 120 | "## 全栈工程师路径图" 121 | ] 122 | }, 123 | { 124 | "cell_type": "markdown", 125 | "metadata": {}, 126 | "source": [ 127 | "既然学了,就肯定不止 Python —— 在扎实的基础之上,学得越多学得越快。以下是一个 “全栈工程师路径图”,作者是位迪拜的帅哥 [Kamran Ahmed](https://github.com/kamranahmedse):\n", 128 | "\n", 129 | "> https://github.com/kamranahmedse/developer-roadmap\n", 130 | ">\n", 131 | "> Below you find a set of charts demonstrating the paths that you can take and the technologies that you would want to adopt in order to become a frontend, backend or a devops. I made these charts for an old professor of mine who wanted something to share with his college students to give them a perspective; sharing them here to help the community.\n", 132 | "> \n", 133 | "> Check out my blog and say \"hi\" on Twitter.\n", 134 | "> \n", 135 | "> **Disclaimer**\n", 136 | ">\n", 137 | "> The purpose of these roadmaps is to give you an idea about the landscape and to guide you if you are confused about what to learn next and not to encourage you to pick what is hip and trendy. You should grow some understanding of why one tool would better suited for some cases than the other and remember hip and trendy never means best suited for the job\n", 138 | "\n", 139 | "## Introduction\n", 140 | "\n", 141 | "![Web Developer Roadmap Introduction](images/intro.png)\n", 142 | "\n", 143 | "\n", 144 | "## Frontend Roadmap\n", 145 | "\n", 146 | "![Frontend Roadmap](images/frontend.png)\n", 147 | "\n", 148 | "## Back-end Roadmap\n", 149 | "\n", 150 | "![Back-end Roadmap](images/backend.png)\n", 151 | "\n", 152 | "## DevOps Roadmap\n", 153 | "\n", 154 | "![DevOps Roadmap](images/devops.png)\n" 155 | ] 156 | }, 157 | { 158 | "cell_type": "markdown", 159 | "metadata": {}, 160 | "source": [ 161 | "路漫漫其修远兮……\n", 162 | "\n", 163 | "但多有意思啊?这完全就是一场闯关游戏。" 164 | ] 165 | } 166 | ], 167 | "metadata": { 168 | "kernelspec": { 169 | "display_name": "Python 3", 170 | "language": "python", 171 | "name": "python3" 172 | }, 173 | "language_info": { 174 | "codemirror_mode": { 175 | "name": "ipython", 176 | "version": 3 177 | }, 178 | "file_extension": ".py", 179 | "mimetype": "text/x-python", 180 | "name": "python", 181 | "nbconvert_exporter": "python", 182 | "pygments_lexer": "ipython3", 183 | "version": "3.7.1" 184 | } 185 | }, 186 | "nbformat": 4, 187 | "nbformat_minor": 2 188 | } 189 | -------------------------------------------------------------------------------- /T-appendix.editor.vscode.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Visual Studio Code 的安装与配置" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "官方文档请查询:\n", 15 | "\n", 16 | "> https://code.visualstudio.com/docs" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "## 允许命令行启动 VS Code" 24 | ] 25 | }, 26 | { 27 | "cell_type": "markdown", 28 | "metadata": {}, 29 | "source": [ 30 | "使用快捷键 `⇧⌘p` 呼出 Command Palette,在其中输入 `shell command`,而后选中 `Install 'code' command in PATH`。此后,就可以在 Terminal 命令行中使用 `code` 命令了。(Windows 系统安装 VS Code 时会自动配置好,并不需要此步骤)\n", 31 | "\n", 32 | "![](images/vscode-shell.png)" 33 | ] 34 | }, 35 | { 36 | "cell_type": "markdown", 37 | "metadata": {}, 38 | "source": [ 39 | "## 选择 Python 解析器版本" 40 | ] 41 | }, 42 | { 43 | "cell_type": "markdown", 44 | "metadata": {}, 45 | "source": [ 46 | "使用快捷键 `⇧⌘p` 呼出 Command Palette,在其中输入 `select interpreter`,而后选中 `Python: Select Interpreter`。\n", 47 | "\n", 48 | "![](images/vscode-select-python-version1.png)\n", 49 | "\n", 50 | "而后,在系统中已安装的若干个版本中选择你需要的那一个。MacOS 系统自带一个 Python 2.7,而我们安装的 Anaconda 为系统另外安装了一个 Python 3.7。\n", 51 | "\n", 52 | "![](images/vscode-select-python-version2.png)" 53 | ] 54 | }, 55 | { 56 | "cell_type": "markdown", 57 | "metadata": {}, 58 | "source": [ 59 | "## 安装扩展" 60 | ] 61 | }, 62 | { 63 | "cell_type": "markdown", 64 | "metadata": {}, 65 | "source": [ 66 | "使用快捷键 `⇧⌘x` 呼出扩展面板。安装 anaconda 扩展,它会连带装上 python 扩展:\n", 67 | "\n", 68 | "![](images/vscode-extensions.png)\n", 69 | "\n", 70 | "另外,为了输入方便,有两个扩展可选安装:\n", 71 | "\n", 72 | "> * Tabout 有它之后,可以使用 TAB 键跳出光标后的括号、引号等等;\n", 73 | "> * Sublime Text Keymap and Settings Importer 有它之后,可以在 VS Code 中使用 SublimeText 的快捷键,最重要的当属多光标编辑 `⇧⌘l`……" 74 | ] 75 | }, 76 | { 77 | "cell_type": "markdown", 78 | "metadata": {}, 79 | "source": [ 80 | "## 自动补全" 81 | ] 82 | }, 83 | { 84 | "cell_type": "markdown", 85 | "metadata": {}, 86 | "source": [ 87 | "专业编辑器最重要的功能之一,就是能够在你输入的时候它帮你做到 “自动补全”,通常使用的快捷键是 TAB 键 `⇥`。\n", 88 | "\n", 89 | "TAB 键 `⇥` 触发的自动补全有两种:\n", 90 | "\n", 91 | "> * 当前文件中已有的字符串。比如,之前你输入过 `sum_of_word`;那么,之后,你就可以输入 `su` 或者干脆 `sow` 而后按 TAB 键 `⇥`,“自动补全” 功能会帮你完成输入 `sum_of_word`\n", 92 | "> * 已有的 Snippets。比如,当你需要输入 `if ...: ...` 的时候,实际上当你输入 `if` 或者甚至 `i` 之后,你就可以用 TAB 键 `⇥`,“自动补全” 功能会为你 “自动完成” 语句块的输入。\n", 93 | "\n", 94 | "字符串自动补全,使用的是所谓的 Fuzzy Match。输入 `sum_of_word` 中所包含的任意字符的任意组合(按顺序),它都会尽量去匹配;所以,`su` 和 `sow` 都可以匹配 `sum_of_word`,再比如,`rst` 可以匹配 `result`。\n", 95 | "\n", 96 | "\n", 97 | "在 Snippet 自动补全的过程中,常常有若干个 “TAB Stop”,即,有若干个位置可以使用 TAB 键 `⇥`(或者,`Shift + ⇥`)来回切换;这时,第一种字符串自动补全的功能就失效了,如果需要使用字符串自动补全,那么需要按快捷键 ESC `⎋` 退出 Snippet 自动补全模式。\n", 98 | "\n", 99 | "以下的 gif 文件演示的是以下代码的输入过程:\n", 100 | "\n", 101 | "```python\n", 102 | "def sum_of_word(word):\n", 103 | " sum = 0\n", 104 | " for char in word:\n", 105 | " sum += ord(char) - 96\n", 106 | " return sum\n", 107 | "with open('results.txt', 'w') as results:\n", 108 | " with open('words_alpha.txt', 'r') as file:\n", 109 | " for word in file.readlines():\n", 110 | " if sum_of_word(word.strip()) == 100:\n", 111 | " results.write(word)\n", 112 | "```\n", 113 | "\n", 114 | "因为有这样的功能,所以你在输入程序的时候其实是非常从容的,可以很慢输入,边思考边输入…… 可实际上,完成速度却很快。\n", 115 | "\n", 116 | "![](images/vscodedemo.gif)\n", 117 | "\n", 118 | "另外,SublimeText 的多光标输入是很多程序员爱不释手的功能,于是,各种编辑器里都有第三方写的 SublimeText Keymap 插件,连 Jupyterlab 都有:\n", 119 | "\n", 120 | "> https://github.com/ryantam626/jupyterlab_sublime" 121 | ] 122 | } 123 | ], 124 | "metadata": { 125 | "kernelspec": { 126 | "display_name": "Python 3", 127 | "language": "python", 128 | "name": "python3" 129 | }, 130 | "language_info": { 131 | "codemirror_mode": { 132 | "name": "ipython", 133 | "version": 3 134 | }, 135 | "file_extension": ".py", 136 | "mimetype": "text/x-python", 137 | "name": "python", 138 | "nbconvert_exporter": "python", 139 | "pygments_lexer": "ipython3", 140 | "version": "3.7.1" 141 | } 142 | }, 143 | "nbformat": 4, 144 | "nbformat_minor": 2 145 | } 146 | -------------------------------------------------------------------------------- /T-appendix.symbols.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# 这些符号都代表什么?" 8 | ] 9 | }, 10 | { 11 | "cell_type": "markdown", 12 | "metadata": {}, 13 | "source": [ 14 | "以下的表格你可以用很多次 —— 每次学一门新语言的时候,都可以拿它整理一遍思路……\n", 15 | "\n", 16 | "最初的时候,人们能向计算机输入的只能是 ASCII 码表中的字符。于是从一开始,计算机科学家们就绞尽脑汁去琢磨怎么把这些符号用好、用足……\n", 17 | "\n", 18 | "于是,ASCII 码表中的字符常常在不同的地方有不同的用处。比如,`.`,在操作系统中,常常当作文件名和扩展名之间的分隔符;在很多编程语言中,都被当作调用 Class Attributes 和 Class Methods 的符号;在正则表达式中,`.` 代表除 `\\r` `\\n` 之外的任意字符……\n", 19 | "\n", 20 | "把下面的表格打印出来,整理一下,在表格里填写每个符号在 Python 中都是用来做什么的?[1]\n", 21 | "\n", 22 | "> 当前文件夹之中,有 `symbols.numbers` 文件,是用来打印以下表格的……\n", 23 | "\n", 24 | "以后不管学什么语言,就拿这个表格过一遍,到时候只有一个感觉:越学越简单!\n", 25 | "\n", 26 | "很多人最初的时候学不进去,就是因为 “一些符号的用法太多了,经常混淆,于是就觉得累了、烦了……” 然而,只要多重复几次多在脑子里过几遍就熟悉了 —— 若是真的熟悉了、若是真的掌握了,你就会觉得:真的没什么啊!哪儿有那么难啊?!" 27 | ] 28 | }, 29 | { 30 | "cell_type": "markdown", 31 | "metadata": {}, 32 | "source": [ 33 | "![](images/symbols.png)" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "学编程的一个好玩之处就是:\n", 41 | "\n", 42 | "> 但凡你学会了任何一门编程语言,你就会发现你的键盘上的每一个键你都用得上……\n", 43 | "\n", 44 | "可是在此之前,你跟人家花了同样的价钱买来的硬件设备,你竟然有那么多根本就没用过的东西!\n", 45 | "\n", 46 | "普通人花同样价钱买来的是台机器而已;可是你却不一样 —— 用同样的价钱买来的是一个特别听话的机器人,一个可以替你不分昼夜不辞辛苦干活的机器人 —— 这感觉非常神奇。" 47 | ] 48 | }, 49 | { 50 | "cell_type": "markdown", 51 | "metadata": {}, 52 | "source": [ 53 | "-----\n", 54 | "**脚注**\n", 55 | "\n", 56 | "[1]:Python 语法,请参阅 The Python Language Reference [2. Lexical analysis](https://docs.python.org/3/reference/lexical_analysis.html#operators)\n", 57 | "\n", 58 | "↑Back to Content↑" 59 | ] 60 | } 61 | ], 62 | "metadata": { 63 | "kernelspec": { 64 | "display_name": "Python 3", 65 | "language": "python", 66 | "name": "python3" 67 | }, 68 | "language_info": { 69 | "codemirror_mode": { 70 | "name": "ipython", 71 | "version": 3 72 | }, 73 | "file_extension": ".py", 74 | "mimetype": "text/x-python", 75 | "name": "python", 76 | "nbconvert_exporter": "python", 77 | "pygments_lexer": "ipython3", 78 | "version": "3.7.1" 79 | } 80 | }, 81 | "nbformat": 4, 82 | "nbformat_minor": 2 83 | } 84 | -------------------------------------------------------------------------------- /from-readers/Cat-self-teaching-stories/aftermy14dayscamptrial.md: -------------------------------------------------------------------------------- 1 | 大家好,我是王露萩,朋友们都叫我cat。我是一名涉外律师,从业13年,常驻北京和洛杉矶。预设目标是能和大家一起互相学习、共同成长。有肥猫垫底,大家请尽情弹跳:) 2 | 3 | 我想要和大家分享的: 4 | **进取型人格、表现型人格是我们探索的工具** 5 | 6 | 它们并不是绝对对立的,但是它们是各自独立的,它们有它们各自的特征,它们就是心理上的工具,帮助我们实现我们的目标。 7 | 8 | 我很多时候会进行不下去一些事情,有客观原因,但如果真诚地面对,我,主观上,尽我所能了么?好像没有,为什么好像,因为不忍面对,为什么不敢面对?因为自己不够“好”,那么什么是“好”?有标尺么?反正我就是不够好了干嘛还要想什么是好,一边去。然后我可能就死机了。 9 | 10 | 咋一想肯定是表现型人格“作祟”影响了自己去进步。可这次的我感受却不一样,如果不是表现型人格的存在,我感知别人的好不会那么强烈。我不会那么容易的记录下来比较出来的结果。 11 | 12 | 而这一次,是我们想明白了,我想要什么。 13 | 怎么想明白的: 14 | 1)之前去拿并拿到加州执照的行动(也不是一开始就想明白一定要,但是最后确信这是自己想要的,行动策略就变化了,学会了求助、获取支持), 15 | 2)看了一遍Absorbent Mind(意. MARIA MONTESSORI)(还在看第二遍),反复思考童年的秘密,“every move counts”,every move {inducted by the freewill execution} counts。 16 | 3)看了两遍“mindset—how we can learn to fulfill our potential”(美.CAROL S. DWECK, Ph.D),那些面对挑战充满了兴趣的孩子们,为什么?为了什么?怎么会这样?我有可能么?怎么做到? 17 | 18 | 我们的结论:我想要探索的工作就是最好的工作。那么既然是我想要的,掌握方法去帮助探索即使很难,也充满了愉悦,因为这意味着我有了工具能更好的探索,这不值得跃跃欲试么? 19 | 20 | **我们的Python训练营探索生活** 21 | 在这次Python训练营的尝试中,反思(Cat me 负责反思和总结加执行,tough guy!scared me,bold me,funny me,jealous me,nuts me,angry me,sad me,anxious me,happy me,and so on , we have lots of mess。。。)我们怎么走的,收获了什么: 22 | 23 | 1. *看到别人的好* 24 | Input: 25 | I1去看 ##move 26 | I2尽量多的去看 27 | I3尽量从这么多里面找到感兴趣的使劲看 28 | 29 | Process: 30 | P1看的同时想“什么是好” ##move 31 | P2在自己感兴趣的那部分使劲想”为什么就是好” 32 | P3看的这么多里面哪个或者哪些是“最好” 33 | P4看得见自己可以模仿的方法了么? 34 | P5能不能试试?能,转到output 35 | While P5 不能? 36 | ##reason:那没看见,不是真在“想” 37 | ##solution:回到P1看的同时想。。。真想。。。 38 | ##如何检验是否“真”想了:使用output 39 | 40 | Output: 41 | O1用纸笔记录怎么进行的I1去看 42 | O2用纸笔记录P1“什么是好”思考的过程与疑问 43 | O3用纸笔记录P2自己感兴趣的部分人家”为什么就是好”的比较理由与列表 44 | O4用纸笔记录P3自己的思考选择以及理由和疑惑 45 | O5我能怎么用这个“好”? 46 | O6我“真”能用这个好的痕迹,运用的每一个点滴 47 | O7这些点滴,我还能用在哪儿呢? 48 | O8记录自己把握的点滴,看到自己的“好” 49 | O9把自己的“好”真实的运用起来,让别人感受到 50 | 51 | 52 | 2. *求助*: 53 | communication意味着什么? 54 | 看见的最快物理接近好的方法论。 55 | 这也是自己*练、做得不够的地方*: 56 | 把握自己的点滴的时候,还是会去因为别人积累的不同而嫉妒,比较的范畴不清晰: 57 | 要看到别人的好,别人这部分展现出来的积累就是ta的好,看见甚至说看了人家的积累过程就是我的收获: 58 | 59 | 因为班里各位同学的认真讨论、分享,我反复读了多遍群内记录,自己好像没有get到他们那么多的收获,有点沮丧,但是,Cat在脑海里马上执行了检验程序: 60 | 我们的收获是什么? 61 | 我们真的没有那么“多”收获么? 62 | 我们要回答上述两个问题必须先回顾: 63 | 我们的记录 64 | 我们把握的点滴真存在 65 | 我们很开心我们看到了别人的好 66 | 我们很开心我们有机会看到自己可以用的好 67 | 我们很开心大家都有自己的收获 68 | 69 | 同时,因为班里同学们的热忱与朝气蓬勃,自己收到了很多的鼓励。 70 | 71 | 不要怕的方法论: 72 | 真。点滴。看到别人的好。与好物理接近。 73 | 74 | 3. *致谢* 75 | 最想感谢Cat, Cat成功的迈开了步子,因为every move counts的信念来源于Cat在此之前迈出去的步子们。。。Cat持续地帮助调整注意力集中到把握我们能把握的点滴上。。。所以。。。不要怕,需要有个方法还需要专门由谁来负责执行,Cat的这个方法也是抄的@核聚(wechat id:hejupai)的“真”与“把握点滴”。 76 | 77 | 感谢互联网让我们能看的更多。 78 | 79 | 感谢互联网上、生活中乐于分享的所有人,让我们的世界充满了美好。 80 | 81 | Cat有幸生活在这个世界,一路上获得了那么多的人的帮助与支持,遇到了李笑来老师,通过笑来老师的眼睛,通过笑来老师的方法与提供的支持,看到了许岑、张旎、mj、老猫、邱老板、和菜头等等老师们的好。有幸遇到了mentor孙志勇老师,他的耐心指导与无条件支持让Cat有机会成长,有机会看到更多的好。 82 | 83 | 感谢我的家人,especially Alucard and Max. 你们包容与支持了各种缺陷的我,陪伴我一起成长。 84 | 85 | 感谢这个训练营的每一位成员,有你们,真好。 86 | 87 | Nonstop the beat! -------------------------------------------------------------------------------- /from-readers/baichangping-self-teachingpython-stories/122.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/from-readers/baichangping-self-teachingpython-stories/122.png -------------------------------------------------------------------------------- /from-readers/baichangping-self-teachingpython-stories/233.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/from-readers/baichangping-self-teachingpython-stories/233.png -------------------------------------------------------------------------------- /from-readers/baichangping-self-teachingpython-stories/54.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/from-readers/baichangping-self-teachingpython-stories/54.png -------------------------------------------------------------------------------- /from-readers/baichangping-self-teachingpython-stories/55.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/from-readers/baichangping-self-teachingpython-stories/55.png -------------------------------------------------------------------------------- /from-readers/junhong-self-teaching-story.md: -------------------------------------------------------------------------------- 1 | # 一个野生程序员的自学之路 2 | 3 | 作者:陈俊鸿(PRESSone 前端工程师) 4 | 5 | 我大学专业是电子工程,主要是研究电路。但毕业之后我并没有从事这方面的工作。最主要的原因是我觉得这个行业很难自学成才。而且这也不是我喜欢的行业。后来有个朋友推荐我学习编程,他让我从前端(写网页界面)入门,因为这样会比较容易。于是我把自己关在房间里面,上网找了一堆教程资料,然后跟着教程写代码,一边看着浏览器运行的结果。当我看到自己的代码在浏览器中实现各种效果,就觉得很有成就感。虽然当时的我对于眼前的代码,还是有很多不懂的地方,但也觉得有意思,好玩。就这样学习了三个月。 6 | 7 | 在这个过程中,我觉得最有意思的是,电脑里面的所有事情,都是我能控制的。只要思路和做法正确,就一定能得到自己想要的结果。我开始喜欢上这个过程。当我能够从头到尾控制一件事情时,我会觉得非常爽。 8 | 9 | 当然了,一开始,磕磕巴巴总是难免的。我总是会遇到一些我解决不了的问题。绞尽脑汁,反复尝试也都是错的。内心很烦躁。于是我学会了一个非常重要的技能:「通过某种方式,使用谷歌搜索」。我学会了如何根据自己的问题,搜索答案。后来我发现,我遇到的大部分问题,别人都有遇到过,网上都有现成的答案。我在这个时刻真正感觉到了互联网是一个神奇的地方。 10 | 11 | 在这个过程中,我也深深体会到英语的重要性。在计算机领域,大部分有价值的信息都是英文的,不会英文将吃大亏。对于英文的要求,也不是很高,够用就行,因为我是一个连四级英语都没考过的同学,现在也能无障碍地用英语,并且还在不断地用,不断地学。有人说:「英语是一个程序员的天花板」,我非常认同。 12 | 13 | 后来,我自学三个月之后,找到了第一份工作。当时的工资很低,但我还是心怀感激,毕竟这为我开启了通往编程世界的大门。这时候我有了新的感悟:在工作中运用知识,和自己私底下练习是很不一样的。因为需要考虑的因素更多,遇到的问题也千奇百怪。在这段工作经历中,我的编程水平成长迅速,我开始觉得:做中学(Learning by doing)是效率最高的学习方式,也是最用有趣的方式。 14 | 15 | 我对于工作的态度就是打怪升级。不断遇到新问题,思考问题,解决问题。不断重复这个过程。于是我慢慢地发现了编程的本质。 16 | 17 | 编程在我看来,其实就是通过计算机解决问题。慢慢地你会发现,你大部分时间不是花在写代码上,而是思考如何解决问题。编程语言就是工具,在开始解决问题之前,我们需要先打磨好工具,所以要先学习语法,学完基础知识之后,就可以开始解决问题。这时候我发现一个很重要的技能 — 分解问题。当遇到复杂的问题时,不要慌,把它分解成一个个小问题,颗粒度越小越好。然后每次只解决一个小问题。最终把所有答案组合起来,就是一段一段代码。我发现这个解决问题的模式,对我的工作和学习帮助非常大。对于处理生活中的事情,也可以遵循这个模式。非常好用。 18 | 编程在我看来,其实就是通过计算机解决问题。慢慢地你会发现,你大部分时间不是花在写代码上,而是思考如何解决问题。编程语言就是工具,在开始解决问题之前,我们需要先打磨好工具,所以要先学习语法,学完基础知识之后,就可以开始解决问题。这时候我发现一个很重要的技能 —— 分解问题。当遇到复杂的问题时,不要慌,把它分解成一个个小问题,颗粒度越小越好。然后每次只解决一个小问题。最终把所有答案组合起来,就是一段一段代码。我发现这个解决问题的模式,对我的工作和学习帮助非常大。对于处理生活中的事情,也可以遵循这个模式。非常好用。 19 | 20 | 每一个新技术都是为了解决问题而诞生的。所以我在学新技术的时候,会围绕这几个方面: 21 | 22 | 1. 这个技术解决了什么问题? 23 | 2. 它的优势是什么? 24 | 3. 它的劣势是什么? 25 | 4. 它和 xx 技术有什么不一样? 26 | 5. 在什么场景下可以使用它? 27 | 6. 如何正确地使用它? 28 | 7. 它的实现原理是什么? 29 | 30 | 学习每个技术,我都会尝试去解答这些问题。有了答案之后,这个技术就可以为我所用。我就知道应该在什么时候,从我的工具箱中把它拿出来用。 31 | 32 | 在学习的过程中,我不太喜欢单纯地啃书看资料。我更喜欢可以立刻看到结果的学习方式。所以我喜欢的教程有如下特点:手把手教程,互动学习,可以做出一个具体作品。因为这样的学习方式,我会觉得更有趣。还是那句话:做中学(Learning by doing)是效率最高的学习方式,也是最用有趣的方式。 33 | 34 | 这些年,还有一个方法,让我获益良多 —— 阅读别人的代码。在我看来,阅读别人的代码,就是在研究别人解决问题的思路。他是怎么做到的?他为什么要这么做?哪里是值得我学习的地方?在计算机领域,很多代码是开源的,我可以看到不同国家的人写的代码,免费从他们的代码中学习。有时候学到了就马上能用在实际工作中,进而提升自己的价值和能力,这种成就感是非常愉悦的。 35 | 36 | 37 | 随着时间的积累,我解决了很多问题,学了很多知识,犯了很多错误。我会使用印象笔记,把这些知识全部都记录下来。好记性不如烂笔头,把有价值的知识整理成体系,让今天花费的学习时间,在将来可以换回对应的价值。学了就忘实在是一种浪费。踏踏实实地把知识记录下来,让自己的努力可积累。现在我可以随手查到自己几年前的学习笔记和总结,这就是一笔财富。我依旧在不断地学习,慢慢地成为一个更厉害的 Problem Solver。 38 | -------------------------------------------------------------------------------- /from-readers/leask-self-taught-stories.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 每个人都值得拥有一根思维的杠杆 3 | author: Leask Wong 4 | date: 2019-03-06 5 | --- 6 | 7 | # 每个人都值得拥有一根思维的杠杆 8 | 9 | 大家好,我是 [@leaskh](https://twitter.com/leaskh)。最近在为 [PRESS.one](https://press.one/) 招聘,为新项目扩充团队,看到不少简历都有让人羡慕的学历,亮眼的从业背景。很多时候我都会问自己,相比于这些候选人,如果让我参加面试,我会有优势么?如何在这个行业可以独当一面,脱颖而出?非不能说是必杀技,但是就学习能力、知识应用和动手能力上,我骄傲一点说,可能比平均水平稍好一些。认识我的人都知道,我是名副其实的 “野生程序猿”,身为红绿色弱的 “残疾人”,在我高考那个年代,是不能报考理工科的,因此我本科学的是经济,这对于当时沉迷计算机并已经开始自己编写软件的我来说,打击十分沉重。但是我凭借自己自学,毕业后成功进入程序开发行业。转眼已十余年,在漫长的自我摸索过程中,有几点想分享一下。 10 | 大家好,我是 [@leaskh](https://twitter.com/leaskh)。最近在为 [PRESS.one](https://press.one/) 招聘,为新项目扩充团队,看到不少简历都有让人羡慕的学历,亮眼的从业背景。很多时候我都会问自己,相比于这些候选人,如果让我参加面试,我会有优势么?如何在这个行业可以独当一面,脱颖而出?非不能说是必杀技,但是就学习能力、知识应用和动手能力上,我骄傲一点说,可能比平均水平稍好一些。认识我的人都知道,我是名副其实的 “野生程序猿”,身为红绿色弱的 “残疾人”,在我高考那个年代,是不能报考理工科的,因此我本科学的是经济,这对于当时沉迷计算机并已经开始自己编写软件的我来说,打击十分沉重。但是我凭借自己自学,毕业后成功进入程序开发行业。转眼已十余年,在漫长的自我摸索过程中,有几点想分享一下。 11 | 12 | --- 13 | 14 | ## 1: 从 “不畏惧动手” 开始。 15 | ## 1: 从 “不畏惧动手” 开始。 16 | 17 | 小时候我特别顽皮,喜欢胡乱拆家里的电器。拆坏,我妈骂我,我爸却从不骂,然后在我面前很有耐心地细致修好。我拆坏东西,他还在别人面前夸我那么小就能用螺丝刀。我爸没什么本事,没挣多少钱,但是这种教育对我产生了深远的影响。从那时起,我就开始不畏惧拆开通电的东西,觉得总能修好,这种心态一直到我后来接触了计算机,我知道对于编写程序而言,就好比你拆开一个玩具,加上新的功能,没弄好的话,重启机器,删代码重来,一遍一遍,总能成。所以当我看到笑来老师这本互动编程教材的内测版本之后相当兴奋,因为我觉得这种打开一个页面,就可以尝试编程,免除了大家零基础接触一个新环境的恐惧,怕把设备搞坏的恐惧,这将是一个美妙的新旅程。 18 | 19 | ## 2: 想办法解决问题,去他妈的基础理论。 20 | 21 | 起初,我之所以想学习编程,其实是希望能开发一个自己的播放软件。我开始去看书,从笨拙地学习控制窗口上的按钮开始,到慢慢知道如何调用解码器,优化资源占用。我并不知道执行这些代码之后,计算机里面发生了什么,但是对我来说,能在界面上看到直观的变化,实际观察到程序的执行结果,令人欢欣鼓舞。我就是这样,从需求出发,像拼乐高一样,完成了自己第一个作品。从做自己想做的事情出发,反向去了解和储备知识,让我把之后遇到的每一个项目,都当成是一次令人愉悦的学习过程。这其中很关键的一点,就是实时反馈:修改->执行,又修改->执行,再修改->执行。这样很容易培养出对代码的亲切感,让你上瘾,不断写,你对代码修改越来越好奇,同时对代码的行为和输出越来越有预期。总之,一开始不要写战线太长、没有成就感的代码,更不要去刨根问底,那是将来的事情,这样会让你陷在其中,丧失兴趣。这也正是为什么我认为如果有一本可以互动修改代码,点一下就能执行看效果的 “书”,可以让初学者少走好多弯路。 22 | 起初,我之所以想学习编程,其实是希望能开发一个自己的播放软件。我开始去看书,从笨拙地学习控制窗口上的按钮开始,到慢慢知道如何调用解码器,优化资源占用。我并不知道执行这些代码之后,计算机里面发生了什么,但是对我来说,能在界面上看到直观的变化,实际观察到程序的执行结果,令人欢欣鼓舞。我就是这样,从需求出发,像拼乐高一样,完成了自己第一个作品。从做自己想做的事情出发,反向去了解和储备知识,让我把之后遇到的每一个项目,都当成是一次令人愉悦的学习过程。这其中很关键的一点,就是实时反馈:修改->执行,又修改->执行,再修改->执行。这样很容易培养出对代码的亲切感,让你上瘾,不断写,你对代码修改越来越好奇,同时对代码的行为和输出越来越有预期。总之,一开始不要写战线太长、没有成就感的代码,更不要去刨根问底,那是将来的事情,这样会让你陷在其中,丧失兴趣。这也正是为什么我认为如果有一本可以互动修改代码,点一下就能执行看效果的 “书”,可以让初学者少走好多弯路。 23 | 24 | ## 3: 完善细节,不要畏惧修改。 25 | 26 | 写程序和绣花差不多,都是相当细致的工作。当一个项目接近完成,就需要开始控制细节,例如输入的边界条件约束,输出效果的美化等等。尝试去细致化你的代码,了解每一行,无论这一行是抄回来的还是自己写的,考虑一下它是不是已经极致,还有没有办法写得更高效和漂亮。当程序已经实现了你想要的功能,那可能仅仅是一个新的开始,不要畏惧尝试修改她,重构她,甚至颠覆她。版本管理工具是你的好朋友,代码的完善也永远没有终点。新思路、新技术的引入,往往会有意象不到的效果,不要畏惧重新开始,只要时间允许,你永远可以写出更优雅的一版。 27 | 28 | ## 4: 善于总结和抽象,回归理论。 29 | 30 | 我一向反对刚开始就去钻研理论,这会让你延迟动手,这让很多人丧失信心,一蹶不振。这好比你学会开车就行,但是从来没有人要求你考驾照要学会修发动机。但是当你的车子开上路了,你想开得更好,希望更省油,希望更安全,你就需要知道一些发动机的工作原理了。同理,这个时候,你要开始理解内存,理解 CPU,理解数据结构,理解编译原理,理解算法等等。当初见成效,就要总结一下自己在这个项目中学到了什么,用了什么技术,是不是如果对某一方面有更深的认识,就可以把这件事情做得更好?这个时候,就是回归理论的最佳时机。赶紧针对性地补课,这将会让你遇到后面的项目的时候,从一开始就站在更高的视野。 31 | 32 | --- 33 | 34 | 我一直觉得学习是一个不断循环迭代的过程,从 “知道自己不知道”,到 “不知道自己不知道”,又回到 “知道自己不知道”……上面说的四点思考,一直帮助我走过了好多次这样的循环。我一直庆幸自己学会了写代码,在遇到问题时,多了一个思考问题的维度。像程序员一样思考和解决问题,会让你更具逻辑性,对资源的制约更有认识。你就像拥有了一根思维的杠杆,只要你愿意,虽不说撬动地球,起码足够颠覆你过往对世界的认识。万物伊始,如果你觉得程序的世界混沌难懂,的确是,“Let there be light”,好奇就是这一道光。 35 | 我一直觉得学习是一个不断循环迭代的过程,从 “知道自己不知道”,到 “不知道自己不知道”,又回到 “知道自己不知道”……上面说的四点思考,一直帮助我走过了好多次这样的循环。我一直庆幸自己学会了写代码,在遇到问题时,多了一个思考问题的维度。像程序员一样思考和解决问题,会让你更具逻辑性,对资源的制约更有认识。你就像拥有了一根思维的杠杆,只要你愿意,虽不说撬动地球,起码足够颠覆你过往对世界的认识。万物伊始,如果你觉得程序的世界混沌难懂,的确是,“Let there be light”,好奇就是这一道光。 36 | -------------------------------------------------------------------------------- /from-readers/liujuanjuans-self-taught-stories.md: -------------------------------------------------------------------------------- 1 | # 我不是技术岗,只是学了点编程 2 | 3 | ## 个人介绍 4 | 5 | - 刘娟娟 6 | 7 | - 1984 年生 8 | 9 | - GitHub: [@liujuanjuan1984](https://github.com/liujuanjuan1984) 10 | 11 | - PRESSone: [行动的女巨人](https://press.one/main/p/ed73e900e209def08ff03a2e3fadbac99af087c0) 12 | 13 | - 10 年游戏行业从业经历,先后服务过网易、4399、三七互娱等 14 | 15 | - 2017 年中开始关注区块链,于2018年初主动离开游戏行业拥抱区块链行业 16 | 17 | - 2018 年 3 月创建 PRS 拓荒者社群,半年后加入 PRESSone BD运营团队 18 | 19 | ## 我的体悟 20 | 21 | 首次读《自学是门手艺》时,我手痒痒,偷时间用 vscode + git 练习,一坐就是两三个小时,如此沉迷几次,玩出来一个自动处理时间开销数据的脚本,顺便把我们团队用来面试程序员的一道 python 题给做了。看了我的代码后,工程师打趣说:你可以来上班了;另一位也颇为乐意鼓励我说:面试时写出这样的代码确实可以考虑招进来。额…… 我代码读得少,莫哄我转岗。 22 | 首次读《自学是门手艺》时,我手痒痒,偷时间用 vscode + git 练习,一坐就是两三个小时,如此沉迷几次,玩出来一个自动处理时间开销数据的脚本,顺便把我们团队用来面试程序员的一道 python 题给做了。看了我的代码后,工程师打趣说:你可以来上班了;另一位也颇为乐意鼓励我说:面试时写出这样的代码确实可以考虑招进来。额…… 我代码读得少,莫哄我转岗。 23 | 24 | 我是一名运营,不是程序员,没有相关的教育或培训经历。2003 年大一首次接触电脑并只必修了 C 语言。2009 年在网易当QC,主程帮我破冰了很多小到不能再小的知识点,让我学会 linux shell 命令行和 mysql 操作,得以独立胜任在无任何游戏界面的情况下完成游戏战斗系统与合服功能的测试。2011 年在网易内部转岗做策划,主程给我找了一本 python 简明教程,我用一个上午浏览语法规则和全书框架,下午就直接读项目的任务系统脚本,并把代码逻辑转换到 excel 中配表。三个月内,我在搜索引擎和简明教程的帮助下,写了几个子类、一些函数以及很多个游戏脚本,其中包括复杂的场景剧情逻辑。这些代码在主程的把关之下全部提交到项目库并正式上线。这两段职场经历中,我都是拿到就用,边做边学。 25 | 26 | 与立志通过自学成为专职的程序员的人不同,我喜欢编程,但尚未想过把它变成职业。单凭兴趣,我还有两段编程学习经历,一次是 2016 年底刚生二宝,参加新生大学 js 入门课,只是因产后上班颇为辛苦而中断。另一次就是《自学是门手艺》。 27 | 28 | 我是如何使用《自学是门手艺》这本书,如何完成了让大家打趣我水平确实不错的代码呢?8年前的那三个月用中学的经历或许让我有些常识和印象,但早已模糊。思来想去,大概是因为:我不善于 coding 但善于拆解需求和迭代代码,我不喜欢硬记于是总是用 google 找答案,且总是把《自学是门手艺》和其它参考书放在手边备查。 29 | 30 | 《自学是门手艺》这本书的使用方法是,先囫囵吞枣,其后多次细细咀嚼。部分章节用于自我激励与充能,部分章节用于纲领性地建立起一个编程知识框架。编程不复杂,老师一句话就概括起来一个非常健壮的框架线条: 31 | 32 | > 从结构上来看,一切的计算机程序,都由且只由两个最基本的成分构成: 33 | > - 运算(Evaluatation)、 34 | > - 流程控制(Control Flow)。 35 | 36 | 我初步掌握编程的方法也并没有超出老师所强调的:练习、拆解、搜索这3条。以我的实践经验来看,这3条也并非孤立,而是同时存在、互相促进。下面以一道简单的题目为例,展示一下我作为初学者是如何以此为契机练习的: 37 | 38 | > 在给出的某篇文章(一份txt文件),统计所有字符的出现次数,并按照次数倒序输出。 39 | 40 | 原始需求经横向初步拆解后,变成: 41 | - 需求 1.统计次数, 42 | - 需求 2.按照次数倒序。 43 | 44 | 需求1又该如何继续横向拆解呢?统计1个字符的出现次数,与统计所有字符的出现次数,后者仅仅是在前者的基础上的一个循环处理。于是就继续拆解为: 45 | 46 | - 需求 1.1 如何统计某个字符的出现次数 47 | - 需求 1.2 一共需要统计哪些字符? 48 | 49 | 如果问题复杂,超出了自己的理解范畴,我就降低问题的复杂程度,然后先写代码实现那个简化版的需求。比如需求 1.1 经纵向拆解后,难度从低到高可以转变为: 50 | 51 | - 需求 1.1.1 统计一个字符串中某个字符出现的次数 52 | - 需求 1.1.2 统计一个列表中某个字符出现的次数 53 | - 需求 1.1.3 统计一个文件中某个字符出现的次数 54 | 55 | 对于初学者来说,文件比列表复杂,列表比字符串复杂,但字符串是基础功。如何处理字符串,初学者能立马通过书本和教程 get 到。虽说文件复杂,但其实一点也不复杂。通过搜索或阅读,你很快就会知道 file.readlines() 可以读取文件返回一个列表,for 循环可以依序处理列表中的每一项,由此打通文件→列表→字符串的路径。 56 | 57 | 并非每次都拆解到基础功,我拆解到自己能掌握的粒度,就开始写代码并运行调试;等这块逻辑通顺了,就写另一块。过程中肯定会遇到困难,我就直接 google 解决办法。带着问题去检索、找到答案、问题解决的这个美妙循环,总是令我一旦编程就停不下来。正因为自己被某个知识点难住,在重读书本的过程中,常常有找到答案的惊喜之感。 58 | 59 | 编程作为一个专业领域,会有很多专有名词。通读《自学是门手艺》全书,熟悉最少必要的专有名词,就能知道大家一般如何称呼,如此将提高准确描述问题的能力并提高检索效率。其实,就连熟悉专有名词这件事,我都不是硬着头皮记忆的。我的专有名词记忆能力实在是差劲,于是我总是把书在手边随时备查,多搜几次就熟悉了。 60 | 61 | 通过练习搜索来精通搜索,通过练习编程来掌握编程。确实没什么新鲜秘诀。 62 | 63 | 这就是我作为一个运营,编程初心者的切身经历。 64 | 65 | --- 66 | 67 | 本文的 [PRESS.one 签名](https://press.one/file/v?s=b54fadaeaa3f6dd3f1fb9eedc1a142b91f7b3271b2b81e2141d5243b49e6139531ad25694e973b22b1b9e6427b9adc4692d78604d7018d12d998d8719a551ea20&h=70e40ae7bfcdf876bade2b9c0c0174a6be8ed86fc47a11439270c65585a7ca09&a=ed73e900e209def08ff03a2e3fadbac99af087c0&f=P1&v=3)。 68 | 69 | 另附:我当时写出来的代码。现在你或许还不会写码,但其实大致能读懂;更或者,你有更好的写法。 70 | 71 | ```python 72 | 73 | import os 74 | import os.path 75 | 76 | """ 77 | 题目: 78 | 文章统计所有字符的出现次数,并按照次数倒序输出 79 | 80 | """ 81 | 82 | testFile ='D:/myfilepath/text_001.txt' 83 | 84 | def main(): 85 | with open(testFile,'rt',encoding='UTF-8') as f: 86 | blines = f.readlines() 87 | 88 | aList = get_chars(blines) 89 | muchtimesDic = count_chars(aList,blines) 90 | 91 | keys = muchtimesDic.keys() 92 | vals = muchtimesDic.values() 93 | rlist = [(key,val) for key,val in zip(keys,vals)] 94 | 95 | Rlist = sorted(rlist,key = lambda x:x[1],reverse = True) 96 | for i in Rlist: 97 | print(i[0],i[1]) 98 | print(Rlist) 99 | 100 | def get_chars(blines): 101 | """ 102 | 功能:获取待检索的字符列表。通过遍历文本,把所有出现的字符列举出来。(大小写不敏感) 103 | """ 104 | aList = [] 105 | 106 | for aline in blines: 107 | aline = aline.lower() 108 | bline = aline[:] 109 | for i in bline: 110 | if i not in aList : 111 | aList.append(i) 112 | return aList 113 | 114 | def count_chars(aList,blines): 115 | """ 116 | 功能:统计字符出现的次数,并返回字典。 117 | """ 118 | muchtimesDic = {} 119 | 120 | for i in aList: 121 | howmanytimes = 0 122 | for aline in blines: 123 | aline = aline.lower() 124 | bline = aline[:] 125 | if i in bline: 126 | howmanytimes = bline.count(i) + howmanytimes 127 | muchtimesDic[i] = howmanytimes 128 | return muchtimesDic 129 | 130 | main() 131 | 132 | ``` 133 | -------------------------------------------------------------------------------- /from-readers/liuyunxin-self-teaching-storise.md: -------------------------------------------------------------------------------- 1 | # 我的自学故事 # 2 | 3 | 说来惭愧,毕业于大专院校,计算机网络专业,属于不好好学那种,之后周围有朋友毕业后又报培训班学起了软件开发,之后工资待遇相当不错,再加上工作后在又在北京认识了一些计算机大拿,再再加上我也是学计算机的,所以我想学编程的自信心和欲望又再次膨胀起来。 4 | 5 | 就这样拖拖拉拉一直从看网上的教程自学开始,加上我在上班,平时只有业余时间看一看,一直没有什么进展,期间接触了李笑来老师的其他课程,英语啊,演讲啊什么的,都是走马观花,随便翻翻。 6 | 7 | 时间一晃过去两年,我还是没学会编程,于是心急下之下我打算去报个培训班,我知道培训班的收费很贵,但是为了学会编程,能换个工作,都值了。就在这个期间,我偶然翻到了笑来老师的网上编程课,而且正是我想学的python,我就报名了。 8 | 9 | 其实我认真想过,决定我报名的原因不是因为笑来老师的名气大,而是他很早以前就讲的学习了学习方法再学习,我深深的认同此观点,所以我知道笑来老师的课,给学生一定提供了一套系统科学的学习路线。学习路线就好比我们上学的时候学校给我们提供的教科书一样,我们不知道为什么要先学这个再学那个,但是有人已经站在高处俯视了整个课题,并给我们规划了这样一个路线,只要严格按照路线走就行。不在像以前那样东一下西一下,一直没进展。而且如果是自学,那么学习路线更重要,还有笑来老师一直讲的自学的理念和学习的方法。 10 | 11 | 说实话,本次一套训练营走下来,我本人最大的感觉就是,编程本身知识没学到多少,但现在敢自学一些自己想学的东西了,觉得编程不难了。为什么,因为当你运用一段代码实现一个功能的时候,哪怕是一个小功能,例如简易版的计算器,这时候就会有一个小的成就感,当然这种成就感转瞬即逝,慢慢的又一个小功能实现,慢慢的一个大功能实现,等积累到一定程度的时候,这时候其实你可以说你已经在这个技能上入门了。 12 | 13 | 我说说我学吉他的经历,上大学的时候一开始和舍友一起弹,他们会弹我不会,我就买了一把吉他跟着他们练,那时候也很着迷,一开始没有研究乐理,直接冲着弹唱去,就开始模仿,生搬硬套,慢慢的会了第一首歌,慢慢的第二首,如此往复,特别是当众表演的时候那成就感更大,别人都知道你会弹吉他这个技能,到后来只弹简单的歌就太low了,就自己去钻研乐理了,然后就可以弹稍微难度大的歌,接着去搞乐队,乐队需要多人协作,必须懂乐理,所以我就更加深入研究乐理,再后来有时候想能不能自己写首歌,就开始瞎哼哼,瞎写歌词,发现写的太low之后就自己去钻研如何作曲,作词。循环往复,这就是我学吉他的一个大概过程。 14 | 15 | 试想一下,如果我一开始就看乐理,看了三个月后,我想上手去弹,结果一弹,自信心就崩了,那我最后很有可能就放弃了,觉得吉他太难,就不学了。只是我想把这个自学经验运用到其他领域的时候,我没想到是因为我先运用后研究理论,我一直以为是因为那时候比较热情,学其他的技能我热情不起来,现在看来,并不是这样。 16 | 17 | 不管怎么说,先上路,然后再研究理论,但是在上路之前,要先掌握一些能上路的基础理论,不能远远的站着看,参与进来。这14节课顶我过去两年的自学成果,就是因为我方法不对,学了那么长时间,完全没有用 18 | 19 | 自学的时候,注意两点 20 | 21 | > 掌握学习路线 22 | > 23 | > 用对学习方法 24 | 25 | 我一开始没有学习路线,东一榔头,西一棒槌,最后失败 26 | 27 | 但是当我学习英语的时候掌握了学习路线,什么听说读写按顺序来的时候,(我们学校的英语教学都是这样的)却还是失败,为什么?没有用对学习方法,没有运用,当然学不好。 28 | 29 | 我现在正在学英语(外教口语一对一视频)以及学编程,周围也有很多计算机编程从业者,这次自学训练营是我的一个拐点吧,它让我认真思考起了什么是自学,怎么自学,感谢笑来老师团队。 30 | 31 | 2019.06.02 -------------------------------------------------------------------------------- /from-readers/lyric-self-teaching-stories.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: 我的自学故事 3 | date: 2019-03-03 4 | --- 5 | 6 | ## 我是谁 7 | 8 | 我是 Lyric,之前曾做过产品经理,所以被称为歌词经理。 9 | 10 | 我最早是一位自由软件开发者,独立开发过多个流行 App;第一份工作在 WeChat 团队,负责产品工作;期间经历对后来的工作影响颇深。 11 | 12 | 我有很多身份,但最喜欢的是 “Maker”:探索互相独立的领域并将他们交融,以期发现新的可能性,并在 “创造” 这件事上推动到极致。 13 | 我有很多身份,但最喜欢的是 “Maker”:探索互相独立的领域并将他们交融,以期发现新的可能性,并在 “创造” 这件事上推动到极致。 14 | 15 | 本文应笑来老师邀而写,发表于 [lyric.im](https://lyric.im/my-self-teaching-stories)。 16 | 17 | --- 18 | 19 | ## 只字不差地阅读 20 | 21 | 在高一下半学期的时候,我弄到了一本 C++ 教材。 22 | 23 | 虽然当时我自认为已经 “掌握” 了 Visual Basic:不仅是在 Visual Basic 里拖动控件组成程序,我还能调用 DLL 里的导出的 Win32 API,甚至 Hook DLL,破解程序,欺骗系统去做我让他们做的事情;不仅是写几个书本上的例子,我还在网络上发布好几个自己做的程序:端口扫描器、字典生成器等等。他们都有真正的用户。 24 | 虽然当时我自认为已经 “掌握” 了 Visual Basic:不仅是在 Visual Basic 里拖动控件组成程序,我还能调用 DLL 里的导出的 Win32 API,甚至 Hook DLL,破解程序,欺骗系统去做我让他们做的事情;不仅是写几个书本上的例子,我还在网络上发布好几个自己做的程序:端口扫描器、字典生成器等等。他们都有真正的用户。 25 | 26 | 不过,我笃信 C++ 是世界上最好的语言,一定要学会它。现实很快表现了它的残酷:在 “继承” 的章节我还能跟得上,但是当教材讲到 “多态” 时我几乎不能理解了。 27 | 不过,我笃信 C++ 是世界上最好的语言,一定要学会它。现实很快表现了它的残酷:在 “继承” 的章节我还能跟得上,但是当教材讲到 “多态” 时我几乎不能理解了。 28 | 29 | 虽然是很简单的概念,但是在那个时候,一个刚接触计算机不到半年的青少年,没有导师,不具备系统性计算机知识,每天只有半小时上机编码的时间,所有的前置知识都来源于一本 Visual Basic 教程和一本姜超著的菜鸟黑客编程手册,学习一门新语言的难度可想而知。 30 | 31 | 当时我采取了**非常笨的办法**:对于书上看不懂的章节,每晚上都在床上读反复地读,一字一句地斟酌其中的含义;读完之后,白天在纸上写下伪代码,放学回家用半小时时间录入代码测试。这样的过程持续了一段时间,直到有一天,我突然理解了所有复杂的 C++ 概念。具体用了多长时间、怎么理解的、习题跑通的高兴心情,等等这些我不记得了,只记得一个结果:**我会了**。 32 | 33 | 后来,我才发现这并非是笨办法,而是**唯一正确的办法**。 34 | 35 | 反复、仔细的阅读不是浪费时间。每一次重新阅读,都会重启思考;每一次思考,都会加深抽象的层次;每一次抽象,都让我离作者更近。就像是小时候背诵古诗词,很难理解其中的美感;但长大后随着思考能力的增强,一旦吟出记忆中的诗句,字句中埋藏的美感就会一一呈现。 36 | 37 | 在大学有机会参与论文写作,导师让我们开始读领域前沿的外文论文,然后写综述。她告诉我们,刚开始肯定都是读不懂的。但你们要一字一字地读,一句一句地理解,最终就能读懂了。这也是科研论文的基本阅读方法。 38 | 39 | 只字不差地阅读是一个只有少数人能获得,并且是自我学习的基础技能,只有获得了这个技能,才算真正的 “**会读书**”。 40 | 只字不差地阅读是一个只有少数人能获得,并且是自我学习的基础技能,只有获得了这个技能,才算真正的 “**会读书**”。 41 | 42 | ## 重复我自己 43 | 44 | 我从小就表现出强烈的绘画兴趣和天赋。那时候家里还没给我请美术老师,但父亲对我做出一个要求:如果想画画,每天完成一幅线稿白描,从蒙纸拓画开始,到能够直接对着画稿临摹。 45 | 46 | 非常不开心。 47 | 48 | 我读过一些画家的故事,他们是一群从内至外都保持自由乃至癫狂的人。我也想要这样,有自由的身体和灵魂,所以我临了萨尔瓦多达利的 “记忆的永恒”(对,就是我们大家都看过的那幅)。 49 | 我读过一些画家的故事,他们是一群从内至外都保持自由乃至癫狂的人。我也想要这样,有自由的身体和灵魂,所以我临了萨尔瓦多达利的 “记忆的永恒”(对,就是我们大家都看过的那幅)。 50 | 51 | ![The Persistence of Memory](lyric-self-teaching-stories/the-persistence-of-memory.jpg) 52 | 53 | 父亲看完后说:“你不懂达利”。 54 | 55 | 确实不懂。达利是一个极具天赋的跨界艺术家。我只看到他梦境中 “软掉的钟”,或者其它怪诞的超现实主义作品;但不了解他如何拥有卓越的绘画和绘图技巧。正如我也不明白**反复临摹是一个学习过程**:不同颜色传达的情绪的差异、从温暖到凉爽的渐变、使用笔画表达力量还是使用晕来表现温柔,所有的临摹都是不断在脑子里塑造这些基本绘画技巧的过程。 56 | 确实不懂。达利是一个极具天赋的跨界艺术家。我只看到他梦境中 “软掉的钟”,或者其它怪诞的超现实主义作品;但不了解他如何拥有卓越的绘画和绘图技巧。正如我也不明白**反复临摹是一个学习过程**:不同颜色传达的情绪的差异、从温暖到凉爽的渐变、使用笔画表达力量还是使用晕来表现温柔,所有的临摹都是不断在脑子里塑造这些基本绘画技巧的过程。 57 | 58 | 高一学会 C++ 后,我把所有用 Visual Basic 写过的程序都用 C++(其实是 C)重写了一遍。在重写过程中,所有 VB 帮我处理的繁琐细节全部在 C 下暴露了出来:没有控件事件,我需要手工处理 Windows 消息循环;没有托管消息,我需要亲自管理 GUI 线程,以免整个程序卡住;诸如 “获取文本”、“设置文本” 这种最简单的操作也需要调用 Win32 API `GetWindowText`, `SetWindowText` 来进行等等。 59 | 高一学会 C++ 后,我把所有用 Visual Basic 写过的程序都用 C++(其实是 C)重写了一遍。在重写过程中,所有 VB 帮我处理的繁琐细节全部在 C 下暴露了出来:没有控件事件,我需要手工处理 Windows 消息循环;没有托管消息,我需要亲自管理 GUI 线程,以免整个程序卡住;诸如 “获取文本”、“设置文本” 这种最简单的操作也需要调用 Win32 API `GetWindowText`, `SetWindowText` 来进行等等。 60 | 61 | 在软件开发领域有一个说法叫 “**重新发明轮子(Reinventing the wheel)**”。指没有意义、浪费资源地重新创造已有事物。但在学习领域,重新发明轮子是重要的方法:不提供结论和关键方法,通过完整地体验其中的过程,让我们领悟其方法的核心精髓,进而掌握其中的思维方式。 62 | 63 | 我进行的这一类重复,不是没有意义的重做轮子。反复地有明确目的地临摹是对基本绘画技能的**重新塑造**,使用 C/C++ 重写程序是对图形化编程底层细节的**重新理解**。 64 | 65 | 后来开始工作了,我发现这二者的重复都造成了深远的影响。对空间、色彩、光线、情绪的理解加上对计算机运作原则的理解,让我不需要把需求转化为设计,也不需要把设计落实在纸面上。我可以敏锐地抓住游离的线索,直接从空气中开始编码,创造我想要的东西。 66 | 67 | 这种 “**从 App 的设计看到背后每一个 Byte 的流动**” 的能力提供了非常多便利,不过这是另一个故事了。 68 | 这种 “**从 App 的设计看到背后每一个 Byte 的流动**” 的能力提供了非常多便利,不过这是另一个故事了。 69 | 70 | --- 71 | 72 | 本文的 [PRESS.one 签名](https://press.one/file/v?s=60791ab3758ba4d2a78a1c0c9ae37a2b9158c78a7f924a0a41fad81c6b29ceea1c9bfcfc39d351574b3521d7fe8b7dc243756753f12f9ea165a44f133f4ba5ee0&h=6c4405e2fbd20ffa671b4cd98e121dbc3d323738fbd6a759e0391b879806e7ac&a=37bb01456229cf59e14aa19c6755a8ba2947be9b&f=P1&v=3)。 73 | -------------------------------------------------------------------------------- /from-readers/lyric-self-teaching-stories/the-persistence-of-memory.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/from-readers/lyric-self-teaching-stories/the-persistence-of-memory.jpg -------------------------------------------------------------------------------- /from-readers/shuimu0579-self-taught-stories.md: -------------------------------------------------------------------------------- 1 | 2 | ## 我眼中的编程 3 | 4 | ### 自我介绍 5 | 6 | > - 我是Suimu,阳历90年出生,前端工程师一枚。大学学的是土木工程,毕业之后做了3年的结构设计,后来转行做前端开发。 7 | 8 | > - Github: [@shuimu0579](https://github.com/shuimu0579) 9 | 10 | > - 个人微信公众号:蚂蚁Fighting 11 | 12 | > - 作为一名程序员,对区块链和数字货币感兴趣。 13 | 14 | ### 编程是什么 15 | 16 | 毫无疑问,编程首先是一种创造性的活动,其目的是为了满足现实世界的各种需求。 17 | 18 | 编程和房屋设计建造很像,都是通过我们的创造,运用模块化工程化的方式,最终建造出好用的产品。他们的不同之处在于,房屋是将图纸中设计意图凝铸成实体,而编程最终输出的不是实物而是充满逻辑性的代码。 19 | 20 | 由于一个交付的产品是实物,另一个交付的是虚拟的产品,因此在房屋建造中一旦实物建造出来了,想要更改就不容易了,而在编程实践中,由于是虚拟的产品,想要对产品进行优化和迭代就会更容易一些。 21 | 22 | ### 心流 23 | 24 | 编程这种创造性的活动,它的本质上就是要不断的解决问题。 25 | 26 | 由逻辑严密的代码构成的软件产品,是要解决现实世界中的痛点,比如微信这样的产品,就满足了人们强烈的社交需求。而在编写软件的过程中,也会遇到各种千奇百怪的问题,解决了这些个问题,软件程序才能顺利的运行起来。 27 | 28 | 在编写代码实现需求的过程中,在修复bug的过程中,时间在安静而快速的流逝,而正在写代码的你却感觉不到时间的飞逝,这或许就是所谓的心流状态吧,沉浸其中,物我两忘。有时候写出来的程序怎么都不work,就会想尽各种办法分析原因找出解决方法,当自己的思路钻进死胡同的时候,这时不如先将问题搁置,放飞思绪,让子弹飞一会儿。如果最终找到问题症结所在,内心就会充盈着满满的成就感,自信心爆棚。在这种死磕的过程中,编程就是这么让人痛并快乐着 —— 山重水复疑无路,柳暗花明又一村。 29 | 在编写代码实现需求的过程中,在修复bug的过程中,时间在安静而快速的流逝,而正在写代码的你却感觉不到时间的飞逝,这或许就是所谓的心流状态吧,沉浸其中,物我两忘。有时候写出来的程序怎么都不work,就会想尽各种办法分析原因找出解决方法,当自己的思路钻进死胡同的时候,这时不如先将问题搁置,放飞思绪,让子弹飞一会儿。如果最终找到问题症结所在,内心就会充盈着满满的成就感,自信心爆棚。在这种死磕的过程中,编程就是这么让人痛并快乐着 —— 山重水复疑无路,柳暗花明又一村。 30 | 31 | ### 自学能力 32 | 33 | 上一家公司有两个同事给我留下很深的印象,有一个小伙子原来的职业是酒吧驻唱歌手,还有一个美国那边的大叔估计有40来岁了吧,原来竟然是个拉小提琴🎻的,我看他们代码写的也还行。看到这些行业转换跨度这么大的同事,坚信了学好编程是可行的,什么时候都不会太晚。 34 | 35 | 学习编程需要我们良好的自学能力,需要我们不断的练习和钻研。而自学能力是我们应该掌握也能够掌握的,相信自己的能力不是固定不变而是能够不断积累提升的;在学习的过程中给自己一些耐心,再多给点耐心,哪怕会出现让人措手不及的问题;修复好了一个bug,也要记得暗暗鼓励自己,因为自信心就是这么一砖一瓦建立起来的。 36 | 37 | 乔布斯2005年在斯坦福大学演讲中讲了三个小故事,让人印象深刻,在演讲的最后,他告诫我们 Stay hungry , Stay foolish. 38 | 39 | 我想说关于编程,我知道终我一生,也绝难达到大师的高度,在接受这一点的情况下,我也会一直在这条路上走下去,我喜欢这样的一段旅程。 40 | 41 | **Stay hungry , Stay foolish.** 42 | -------------------------------------------------------------------------------- /from-readers/sxuya-selfteaching-story.md: -------------------------------------------------------------------------------- 1 | 2 | # 第一遍学完项目感想记录 3 | 4 | ## 时间方面 5 | 6 | 从3月底开始,到现在5月出,基本上算是话费了 1 个月的时间将项目的内容从头到位看过了一遍。 7 | 8 | 平均下来,自己一个星期大致会花费多少时间呢?大概有6-8个小时吧。 9 | 10 | ## 学习背景方面 11 | 12 | 自己有一些编程的入门尝试经验,所以能够进入课程按照章节内容进行学习还是相对来说比较容易的。 13 | 14 | 之前在 Udacity 学习过一个课程内容,对于 jupyter notebook 的使用还是有经验的,所以应该相对刚刚接触这个软件的人来说,会比较容易上手。对于一些遇到的问题,知道大致的解决方法,会比较快地去定位寻找方法。 15 | 16 | 但是,第一次接触的同学也不用在意,各种视频网站上面有很丰富的使用入门视频,内容相对来说差别不大,只要找到一个入门教程,那么一步步跟着做下来,然后在自己反复摸索、复习一下,就可以明白使用的逻辑了。 17 | 18 | PS:即使有经验,在初次配置 xiaolai 老师的环境的时候,也遇到了之前没有遇到过的问题,也坎坷了很久,还采取了「卸载、重新安装」的方法进行解决,但是也不是顺利解决,也还是多找了一些资料进行分析,找到了原因。 19 | 20 | 即使这样不顺利,但是也学习到了很多新的内容,所以,遇到问题不怕,这个正是学习成长的重要时间。 21 | 22 | 23 | 24 | ## 学习方法方面 25 | 26 | 大家一定要养成**记录笔记、日志或者发帖**的习惯。 27 | 28 | 这是自己学习经历的一个提醒。 29 | 30 | 有很多内容当时遇到,寻找到方法并且解决了,但是以前的自己没有养成记录的习惯,所以即使曾经成功解决了的问题,过了一段时间再遇到,还是会想不出来自己以前到底怎么具体解决的,回看浏览器的记录,也很难顺利找到答案。 31 | 32 | **我后来的方法:** 33 | 34 | 在课程 repo 里面的 ```my-notes``` 里面开了几个 ipynb 文件,在学习课程内容的过程里,记录学习过程中遇到的不同的内容、问题,如果有新的理解,就同样记录起来,进行迭代升级。 35 | 36 | 这样的做的好处,就是以后即使忘记了具体内容,但是可以快速索引到自己问题的针对性解决方法。 37 | 38 | 真的后悔为什么没有早点醒悟出这一点。 39 | 40 | ## 进入门槛——GitHub 41 | 42 | 即使像我这样已经有一定的学习的基础,但是也没有具体好好使用过 GitHub,所以,在进入学习的开始阶段,被 GitHub 的 pull request 的操作搞得很难受,前后捣鼓了 1 个星期左右,才算是真正学会了 Git 的逻辑关系。 43 | 44 | 虽然很难,也正如一位曾经的编程高手说的:「GitHub 让所有人觉得自己很愚蠢」,but,真正学会了其中的逻辑和哲学思想,那真的是一件超级强大的工具,除了编程方面,还有很多方面值得我们去使用、探索。 45 | 46 | 这方面具体的内容见下面连接,是自己之前学习过程中写的这一点的心得体会,希望对你有所帮助: 47 | 48 | [Github进行fork后如何与原仓库同步:重新fork很省事,但不如反复练习版本合并 #67](https://github.com/selfteaching/the-craft-of-selfteaching/issues/67) 49 | 50 | ## 暂存的问题 51 | 52 | 部分章节的内容也是全新学习的新知识,有些内容琢磨明白了,但是还是有些内容不清楚——而这些内容就是自己第二遍学习的时候重点注意的内容了,需要反复查询资料进行攻克的内容了。 53 | 54 | 学习过,但是还不是很明白的内容,大致有下面这些内容: 55 | 56 | 1. lambda 函数的使用。(就是数学里面的那个希腊字母的英文) 57 | 1. recursion 的逻辑再次梳理。 58 | 1. 「tdd 测试驱动开发」的再理解 59 | 1. 「BNF 和 EBNF (扩展)巴科斯-诺尔范式」的理解。完全不知道到底和 RE 有什么区别。 60 | 1. …… 61 | 62 | 暂时记录在这里,在接下来的第二遍过一遍的时候,再看看这些问题会不会有一些得到理解、进步。。 63 | 64 | ## 最大的不同(特点) 65 | 66 | xiaolai 这个「入门」教程最大的不同,或者说是特点,就是完全从一个全新的角度,定义了「入门教程」可以有的形态。 67 | 68 | 再次之前,所有的入门教程,都是一个个小点、知识点讲解,并且使用的语言还是那么刻板,或者说死板,很难让一个新生理解所学新领域的特点和内容,而很多基础内容由于这个原因,无法继续下去,也就「从入门到放弃」。 69 | 70 | 而 xiaolai 是将读者看作一个有主观能动性的个体,所以不会在细节上讲解,即「不会授人以鱼」;而是,有自己学习过程中遇到的感受、以及解决方法的升级的过程的展示,相当于以一个朋友的角色,将内容娓娓道来,让读者欲罢不能,感觉有一个伙伴和自己一起学习,那种陪同的感觉实在是太美妙了,是见过的入门教程所从来不具有的高度。 71 | 72 | 正如 xiaolai 自己定位的,是把这个教程当作 Python 官方文档的引入、注释类的地位——相比就是是因为叫这个教程定位为「授人以渔」,所以里面有大量的链接,值得自己后期在按图索骥进行更加深入的学习。 73 | 74 | ## 最大的收获 75 | 76 | 要说最大的收获,那其实我想说的是入门的「GitHub 的学习和使用」,项目里面具体编程内容,反而没有那么大深刻印象。 77 | 78 | 在探索的过程中,发现问题、有什么想法,就尽可能去提交 PR,让自己头脑中不确定的想法得到一个正向反馈——更加兴奋的是这个反馈直接来自 xiaolai 老师,万分喜悦。 79 | 80 | 而在这一次次提交 PR 的过程中,对于 GitHub 的逻辑越来越熟悉、操作越来越顺手。 81 | 82 | 下面是第一遍学习提交的 PR 成果: 83 | 84 | ![PRsLogs](https://github.com/sxuya/the-craft-of-selfteaching/blob/sxuyaStudy/my-notes/PRsLogs.jpg?raw=true) 85 | 86 | 前后包括重复、试错的次数,一共 20 个,其中 7 个被 merge 到项目中(还有个别虽然没有 merged,但是也从 xiaolai 的评论里面得到了很好的交流),有 **35%** 的 merge rate,这个比例让刚刚大致学会 GitHub 和 协同工作的我来说,是一件及其喜悦的事情: 87 | 88 | ## 庆幸 89 | 90 | 庆幸自己在项目的开始的时候,就知道了他的存在,从而进入到项目的学过程中,能够在「毛项目」有最多的迭代可能性的时候,不断学习,自己精进的同时,能够和项目一起升级,这种感觉实在是美妙。 91 | 92 | 回想之前得知项目后,还是拖延了 1 周才开始好好了解项目的内容,如果没有动手进入,错过了「项目学习的黄金时间」,那真的不知道自己的世界会变得多么的可悲,「不知道自己可悲其实是最大的可悲」。 93 | 94 | 后面加入学习的「同学们」也不用气馁,在我们开辟、完善的「新」项目里,少了很多不必要的坑,你们的学习效率会比我们大很多,今后还有很多其他的项目、内容值得我们去摸索。 95 | 96 | 或者,给个 xiaolai 老师的那个建议:**想要获得我们那种完善项目一起升级的美妙感觉,可以用一个全新的方式进行:「教别人」。** 97 | 98 | 「教别人」的过程里,会看到更多本来书上有、但是被自己忽视掉认为理所当然可以解决的坑,在这个过程里,你自己就升级了——在回答 ```issue``` 里面的帖子的时候,也看到了形形色色其他人的问题,虽然自己理解了,但是使用文字进行回复、讲解明白,还是会重新获得**新的认识**,自己也升级了。 99 | 100 | ## 祝福 101 | 102 | 祝这里所有学习的人,都学有收获,或大或小,加油~ 103 | -------------------------------------------------------------------------------- /from-readers/xiaoqiang-self-teaching-stories.md: -------------------------------------------------------------------------------- 1 | # 牛逼的思想者 2 | * 最近几年,每年基本思想都有一个提升,我一直以为只要思想牛逼重要,其他的都不重要。 3 | 甚至我本身是学软件出身,但是毕业之后,一天代码都没写,学的东西全部送回给老师了。 4 | * 前两年因为在国外工作,曾经一度想把英语学好,结果学了两三个月, 最后放弃了。 5 | 最近由于接触到李老师的这本书,又重新捡起来了。 6 | 甚至也给自己定位为终身学习者。 7 | * 很讽刺,早几年前,实际我知道git很牛逼,github也很牛逼,甚至一度也下载了相关软件来安装,学习使用,但是因为命令看着太过头痛,加之,没有彻底了解github的运行原理,没有发现github的伟大。 8 | 这次在李笑来老师的影响下,硬着头皮去真正了解了下。 9 | 终于把github整个使用熟悉了,包括如何pull request,如何合并别人的pull request。 10 | * 突然发现,一旦你下定决心去搞懂一个东西,实际上,你会发现,并没有你想象的那么难。 11 | 所以对于英语,我发现我有重拾回了信心。 12 | * 以前我学东西,老想找捷径,通过李老师的书,真正明白了,学习,无非就是花时间,只有时间花到位了,哪怕你不用任何方法技巧,都能起到很好的效果。 13 | * 在没接触李老师的时候,我对李老师印象不好,主要是外界的各种消息,扰乱了我,让我觉得李老师跟孙晨宇是一路货色,真正看了老师的一系列书之后,我发现,李老师真的深不可测,毕竟几十年如一日的学习加持,这不是一般人能做的到的。 14 | * 希望自己也能几十年如一日的学习,他日财富自由了,一定的当面感谢李老师。 15 | * 这篇文章作为一个见证吧。 16 | -------------------------------------------------------------------------------- /from-readers/zhangmmin-selfteaching-camp-story.md: -------------------------------------------------------------------------------- 1 |  2 | # 提交练习作业的目录 3 | 4 | 从2019.03.27 到2019.05.29 ,64天,用时约90h, 上交了13份作业。 5 | 6 | 为什么想加入这个训练营呢?1.想学习更多的技能 2. 想把自己的时间花在有意义的事情上 7 | 8 | 9 | 刚开始是想报14天连续完成的模式的,想在英文读不懂,也没有计算机基础,而且只有晚上几个小时的情况下去挑战一下自己,看自己到底能做到什么程度,但提前体验了第一天的任务。从阅读到安装差不多就用了一天的时间,我知道自己当时的能力做不到连续完成。最后选择自由时间完成作业的模式。 10 | 11 | day1- day4,虽然用时很长,主要是阅读材料 ,遇到的问题可以直接在issues中或是搜索引擎中搜索到,能自己完成。 12 | 13 | day5  是第一次接触词频统计的代码,看完阅读材料也没什么用,不知从何下手,不知道自己有哪些问题,搜索出来的统计词频的案例,也全都看不懂,也不知道怎么用到自己的作业中。想去issues中找答案,可是没有自己想要的,陷入了自己非常想解决问题,并且付出了努力,可就是做不到的困境;同时看到与我同时段开始学习的人,就快要完成所有的作业了。更让我对自己产生了极大的怀疑,我是不是很笨,为什么别人都能做到,为什么就我不行呢?明明我都已经看了好几遍了,可为什么就是不懂?就是不会做呢?这种想法一旦萌生,就会陷入恶性循环,甚至会使我对我的未来产生怀疑,丧失信心。但同时又有另外一种声音告诉我,“不行,既然别人能做到,那我也能做到。”当时,在issues中看到有一位同学在day5也遇到了困难,也像我一样会怀疑自己,虽然这有一点安慰,但是还是不足以让我摆脱失落,难过。看到糖果中也有其他人也遇到同样的困境,我才明白“原来,我并不孤单,不只我一个人是这样。”“既然别人能做到,我也能做到”+“原来,我并不孤单”使得当时的我在自卑的阴影中继续前行。最终,觉得既然自己解决不了问题的话,那就寻找他人的帮助吧。我怀着不安,歉疚 的心情看了别人的作业,并且把他照搬到我的作业中去。 14 |       15 |      接下来的作业,当我遇到自己实在解决不了的问题的时候,我又会怀着愧疚的心情(虽然老白说刚开始学习一门新技能的时候,模仿和借鉴是最快速实现目的的方式)打开的别人的作业,看别人的代码是怎么样的,从刚开始的照搬到之后将自己的一部分代码与他人的代码结合起来。有时候,我会怀疑自己这样是否真的能学到东西呢? 16 |   17 |      直到完成day9 day10的作业时,发现正因为照搬别人的作业而完成了作业,才能越来越理解之前的作业,才能慢慢地有自己的思路,以至于能越来越好地完成当前的作业。   18 | 19 |      实战演练真的很好玩,特别是将结果自动返回给朋友,当代码运行成功之后,会很兴奋,很开心。 20 | 21 |      每次的作业平均可能要花上一周的时间,期间有痛苦,有焦虑,有怀疑,遇到困难,有逃避,松懈的状态,但也不知道为什么还是完成了所有的作业,可能还是有一颗向上的心吧。 22 | 23 |     day5 可能是我觉得最难的时候,感谢让我觉得不是一个人的同学们,使得我能继续的往下走,现在才能发现在学习python的这段时间,我的生活是这么的充实。也更让我明白: 24 | 1. 最困难的时候总会过去,这个时候告诉自己,你并不孤单,再坚持一下。挺过去了,回头再来看,真的没什么,反而会感谢这段让人痛苦的日子,因为它,才能发现通过自己努力收获到的果实原来这么的甜。 25 | 2. 不去跟别人比较,只关注自己的成长就行,因自己的进步而开心。 26 | 3. 在刚开始学一门技能的时候,更应该接受自己的笨拙。 27 | 4. 把自己遇到的问题,把自己的想法分享出来,真的能帮到别人。我因其他同学发的issues获益良多。但是,每当自己遇到问题的时候,却不想发issues,总是想着自己去解决,也不想向教练求助。这种矛盾的心理我也不知道该如何解决。 28 | 5. 模仿,借鉴并不可耻。模仿别人能让自己了解这项技能,能让自己更快地成长,在模仿中也能逐渐探索出自己的方法。不让模仿成为放弃的借口。 29 |        6. 养成记录的习惯。记录自己遇到的问题,记录自己的收获,给自己走过的路留下一点痕迹。 30 |        7. 学会向别人求助。可是不知道为什么自己就是做不到。 31 |        8. 把学到的东西用在自己的生活中,会更有趣,更好玩儿。 32 | 33 | 34 | 生活中的一个改变是:遇到问题,更多的是想如何通过自己的努力去解决它,也认为一定会有解决的办法的。 35 | 36 | 目前,关于Python还有很多不懂的地方,对于下一步,有些迷茫。但是还是想继续往下学,那就先给自己定个目标:将笑来老师的书《自学是门手艺》完整的看一遍,将其中的代码再手打一遍。 37 | 38 | 39 | 最后 ,感谢教练,辅导员这段时间的关心和鼓励,感谢训练营中同学的帮助和陪伴,也感谢在实战演练中被我一直骚扰,给予我支持,耐心的yr姐姐。 40 | 41 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /from-readers/zhangqis-self-taught-stories.md: -------------------------------------------------------------------------------- 1 | # 我的自学故事 2 | 3 | ## 个人介绍 4 | 5 | * 章琦 6 | * 1995年生 7 | * GitHub: [@qinix](https://github.com/qinix) 8 | * 北航统计学学士 9 | * 开源贡献者,[Rails Contributor](https://contributors.rubyonrails.org/contributors/eric-zhang/commits), [Elixir Contributor](https://github.com/elixir-lang/elixir/commits?author=qinix) 10 | * 10+ 年编程自学者 11 | * 前由你单车后端架构师 12 | * 前 Yunbi、BigONE、Peatio 技术专家 13 | * BigONE & Peatio 高性能交易撮合引擎作者,高峰期日成交量十亿美元 14 | * Venezia 区块链资产管理系统作者,安全管理交易所上百亿数字资产 15 | * Mariana 内部量化交易系统负责人 16 | * 海洛创意签约摄影师 17 | * 古典吉他和指弹吉他演奏爱好者 18 | 19 | ## 兴趣的源头 20 | 21 | 我是在小学五年级时候第一次接触到了编程,并且幸运的对编程这件事产生了极大的兴趣。回想起来,当时对这件事一直保持着兴趣的想法很简单: 22 | 23 | > 学会了这个技能我就可以用它去做很牛逼很酷炫的事情,想想就很有**成就感**。 24 | 25 | 相比于在学校里学数学、学历史,学编程带来的反馈很直接,直抵神经。 26 | 27 | 像很多人一样,我一开始学了 C 语言。很不巧,C 语言显然不是一个学一学就能做出很牛逼很酷炫的事情的语言。到目前为止(2019 年),市面上的所有 C 语言书籍都只能教你语法和在黑底白字的终端下面做一些习题。任何一个刚学编程的人看完了这样的书都是一脸懵逼,完全不知道学了这样的编程能有什么用。 28 | 29 | 由于当时还对计算机硬件感兴趣,我顺势接触到了 51 单片机。单片机第一次让我看到了编程能怎么用在现实生活中。我可以用 C 语言控制 LED 小灯的亮灭、蜂鸣器的响声、电机的转动。甚至想到了用单片机实现远程控制开关家里的电灯 —— 也就是后来的智能家居,当时是 2008 年。 30 | 由于当时还对计算机硬件感兴趣,我顺势接触到了 51 单片机。单片机第一次让我看到了编程能怎么用在现实生活中。我可以用 C 语言控制 LED 小灯的亮灭、蜂鸣器的响声、电机的转动。甚至想到了用单片机实现远程控制开关家里的电灯 —— 也就是后来的智能家居,当时是 2008 年。 31 | 32 | 随着由单片机对我带来的编程世界观的改变,我找到了更多工程中直接使用的编程语言和框架,例如:Ruby、Ruby on Rails、Python。使用这些语言,我能更快的完成我想做的事,给我更直接的刺激感和愉悦感,产生**正向反馈**。 33 | 34 | ## 一万小时有多久 35 | 36 | 格拉德威尔在《异类》一书中指出: 37 | 38 | > 人们眼中的天才之所以卓越非凡,并非天资超人一等,而是付出了持续不断的努力。1万小时的锤炼是任何人从平凡变成世界级大师的必要条件。 39 | 40 | 那么,一万小时有多久呢? 41 | 42 | > * 如果平均每天学习和刻意练习 4 个小时,一共需要 2500 天,也就是 6.85 年; 43 | > * 假如一个人从 18 岁开始知道自己该干什么,到 65 岁退休,中间一共有 47 年; 44 | > * 假如一个人从 18 岁开始可以学习和练习一个技能,并且每天投入 4 个小时,那么只需要到 25 岁就可以成为这个领域的专家; 45 | 46 | 总有人问我是怎么自己学会编程的,我想了一下,可能最重要的点就是: 47 | 48 | > **花时间,花很多时间** 49 | 50 | 上初中和高中的时候,由于学校使用电脑不太方便,我会坚持每天睡前在手机上阅读技术文档至少两小时,并且通过手机远程 ssh 连接到租用的 Linux 云主机上实践编程。由于手机没有实体键盘,并且虚拟键盘没有方便的上下左右键,我还因此顺便学会并且熟练使用 vim 键位。 51 | 52 | 后来上了大学的常态就是,每天起床后往电脑前一坐就是一天,看书、看文档、看源码、写代码。往往每天都能学习十个小时以上。 53 | 54 | 工作之后,我会尽量避免去做那些已经非常熟悉的事,尽可能把工作也变成一种学习。 55 | 56 | 这样想来,可能不需要 6.85 年就能达到 10000 小时了呢? 57 | 58 | ## 去做一些事 59 | 60 | ### 将刚学的技能用起来 61 | 62 | 几乎所有事情都是这样: 63 | 64 | > 「你以为你学会了」和「你真的学会了」是完全不同的两码事 65 | 66 | 你以为你看完了一本编程书,已经学会了书中的知识。但真的在工作中用的时候,才发现还是不得不再拿出书放在旁边,一边看一边做。 67 | 68 | 实际上,这并不是什么坏事,其实所有人都是这样。只有在做过大量练习之后,才是真正学会了这个知识,抛弃书本,灵活使用。 69 | 70 | 而在做编程练习时,有一个很讨巧的办法: 71 | 72 | > 用你刚学的技能去接个活儿 73 | 74 | 高中时候,我第一次接触到了 Ruby 和 Ruby on Rails,作为一个 Web 快速开发框架,市面上到处都是对口的外包项目。我在学习完全部基本概念之后顺势接了个外包项目,用 Rails 开发,第一次做出了一个完整的产品,练习了技能的同时还得到了经济收益。 75 | 76 | 这个方式去练习编程有几个好处: 77 | 78 | > 1. 强迫你完成这件事,毕竟已经承诺了别人 79 | > 2. 通过做出完整的作品,可以学习到很多教程中没有提到的细节 80 | > 3. 顺便还能产生经济收益 81 | 82 | ### 目标导向 83 | 84 | > 如果始终无法下定决心来学一个东西的话,那就先把学会它之后用它做个什么东西想好。 85 | 86 | 刚上大学时候,我想尝试一下学习 iOS 编程。但拖延症嘛,始终觉得暂时用不到,就没有开始学。 87 | 88 | 后来,总觉得不能闲着,该干些什么事。于是决定写一个学生课程表查询、成绩查询的 app。恰好北航是一个保密性比较强的学校,外边的超级课程表、课程格子都没有接入北航内部数据,学校里面也没有人在做这个事,这个事在当时是一个很大的缺口。 89 | 90 | 确定下来要做什么之后,我才开始一边学一边做。一旦学起来之后,一切都变得容易了。一个人一边学一边做,最终只用了不到两周就完成了第一版的上线。遇到不会的东西怎么办?自己 Google 呗…… 反正要做出来东西。 91 | 确定下来要做什么之后,我才开始一边学一边做。一旦学起来之后,一切都变得容易了。一个人一边学一边做,最终只用了不到两周就完成了第一版的上线。遇到不会的东西怎么办?自己 Google 呗…… 反正要做出来东西。 92 | 93 | 后来,这个 app 用户面甚至覆盖了超过一半的本科生…… 94 | 后来,这个 app 用户面甚至覆盖了超过一半的本科生…… 95 | 96 | 对于编程来说,一个人自己学着做还是会有一个致命的缺点 —— 限制了学习的角度和深度。因此,我为了更加深入学习 iOS,加入了美团的 iOS 基础架构组。在那里学习了大型应用是如何组织起来的,并且为了实现应用热更新还重头实现了一个面向对象语言运行时。 97 | 对于编程来说,一个人自己学着做还是会有一个致命的缺点 —— 限制了学习的角度和深度。因此,我为了更加深入学习 iOS,加入了美团的 iOS 基础架构组。在那里学习了大型应用是如何组织起来的,并且为了实现应用热更新还重头实现了一个面向对象语言运行时。 98 | 99 | ## 不要害怕 100 | 101 | 要深入学习一个编程语言或框架,其实方式很简单: 102 | 103 | > 1. **通读**文档或对应论文 104 | > 2. **精读**源码 105 | 106 | 通常,一个成熟的项目从文档就可以学到大部分细节。 107 | 108 | 不过,大部分人对于直接阅读项目文档和源码都存在着恐惧心理,感觉那是「搞科研」的人干的事。 109 | 110 | 有的人是觉得语言不通,其中包括自然语言(英语)和符号语言(数学)。其实语言这种东西,不要被吓住,习惯就好了…… 111 | 有的人是觉得语言不通,其中包括自然语言(英语)和符号语言(数学)。其实语言这种东西,不要被吓住,习惯就好了…… 112 | 113 | 在深入学习 Rails 的时候,我一字不差的通读了 Rails 的文档,并且仔细阅读了路由系统、ORM 底层实现的源码,**甚至**还自己从头实现了一个简单的 Ruby 编译器和 Rails-like Web 框架。都做完了之后发现,**根本没有那么难嘛**,都是外面人骗你和自己吓唬自己。 114 | 115 | 后来进入了区块链领域,由于工作需要重新实现很多链的交易构造和签名逻辑,仔细阅读了《比特币白皮书》和《以太坊黄皮书》,逼着自己读完之后发现其实根本也没有看起来那么难嘛。明明比网络上流传的大部分文章讲得清晰又简洁,却因为标题和一些数学符号拦住了很多人,其实数学符号和学英语一样嘛 —— 遇到不会的**查**就是了。 116 | 后来进入了区块链领域,由于工作需要重新实现很多链的交易构造和签名逻辑,仔细阅读了《比特币白皮书》和《以太坊黄皮书》,逼着自己读完之后发现其实根本也没有看起来那么难嘛。明明比网络上流传的大部分文章讲得清晰又简洁,却因为标题和一些数学符号拦住了很多人,其实数学符号和学英语一样嘛 —— 遇到不会的**查**就是了。 117 | 118 | 值得一提的是: 119 | 120 | > *《比特币白皮书》除去附录只有 8 页,带来的比特币市值一度超过了 3200 亿美元; 121 | > *《比特币白皮书》除去附录只有 8 页,带来的比特币市值一度超过了 3200 亿美元; 122 | > *《以太坊黄皮书》除去附录只有 15 页,用优雅的符号语言描述了以太坊的所有细节:传说当年找了几个不同编程语言的团队互相隔离,都对着这个黄皮书来做实现,实现出来的东西竟然是互相兼容的。 123 | > *《以太坊黄皮书》除去附录只有 15 页,用优雅的符号语言描述了以太坊的所有细节:传说当年找了几个不同编程语言的团队互相隔离,都对着这个黄皮书来做实现,实现出来的东西竟然是互相兼容的。 124 | -------------------------------------------------------------------------------- /hdi-china-1870-2015.txt: -------------------------------------------------------------------------------- 1 | 1870, 0.04 2 | 1880, 0.04 3 | 1890, 0.05 4 | 1900, 0.04 5 | 1913, 0.04 6 | 1925, 0.05 7 | 1929, 0.07 8 | 1933, 0.08 9 | 1938, 0.09 10 | 1950, 0.12 11 | 1955, 0.16 12 | 1960, 0.15 13 | 1965, 0.23 14 | 1970, 0.25 15 | 1975, 0.28 16 | 1980, 0.29 17 | 1985, 0.3 18 | 1990, 0.31 19 | 1995, 0.35 20 | 2000, 0.39 21 | 2005, 0.42 22 | 2007, 0.46 23 | 2010, 0.48 24 | 2015, 0.54 -------------------------------------------------------------------------------- /images/2_necker_cubes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/2_necker_cubes.png -------------------------------------------------------------------------------- /images/Acorn-Electron.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Acorn-Electron.png -------------------------------------------------------------------------------- /images/CC-BY-NC-ND.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/CC-BY-NC-ND.png -------------------------------------------------------------------------------- /images/Joseph-M-Williams-research-visualized.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Joseph-M-Williams-research-visualized.png -------------------------------------------------------------------------------- /images/Lamarr_patent.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Lamarr_patent.png -------------------------------------------------------------------------------- /images/Part.1.A.better.teachyourself_2_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Part.1.A.better.teachyourself_2_0.png -------------------------------------------------------------------------------- /images/Part.1.A.better.teachyourself_4_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Part.1.A.better.teachyourself_4_0.png -------------------------------------------------------------------------------- /images/Part.1.A.better.teachyourself_6_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Part.1.A.better.teachyourself_6_0.png -------------------------------------------------------------------------------- /images/Part.1.E.6.containers_66_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Part.1.E.6.containers_66_0.png -------------------------------------------------------------------------------- /images/Phylogenetic_tree.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Phylogenetic_tree.png -------------------------------------------------------------------------------- /images/Tree-of-Life.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Tree-of-Life.gif -------------------------------------------------------------------------------- /images/Unix_Glob_Reference.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/Unix_Glob_Reference.png -------------------------------------------------------------------------------- /images/a-cartoon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/a-cartoon.png -------------------------------------------------------------------------------- /images/apple-keyboard.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/apple-keyboard.png -------------------------------------------------------------------------------- /images/archimedes-eureka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/archimedes-eureka.png -------------------------------------------------------------------------------- /images/arguments-order.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/arguments-order.png -------------------------------------------------------------------------------- /images/backend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/backend.png -------------------------------------------------------------------------------- /images/boolean-operators.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/boolean-operators.png -------------------------------------------------------------------------------- /images/class-variables-scope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/class-variables-scope.png -------------------------------------------------------------------------------- /images/code-review.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/code-review.png -------------------------------------------------------------------------------- /images/continue-break.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/continue-break.png -------------------------------------------------------------------------------- /images/controlflow-function.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/controlflow-function.png -------------------------------------------------------------------------------- /images/decompose-x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/decompose-x.png -------------------------------------------------------------------------------- /images/decompose-y.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/decompose-y.png -------------------------------------------------------------------------------- /images/devops.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/devops.png -------------------------------------------------------------------------------- /images/disclaimer.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/disclaimer.png -------------------------------------------------------------------------------- /images/doc-class.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-class.png -------------------------------------------------------------------------------- /images/doc-divmod.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-divmod.png -------------------------------------------------------------------------------- /images/doc-exec.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-exec.png -------------------------------------------------------------------------------- /images/doc-max.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-max.png -------------------------------------------------------------------------------- /images/doc-pow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-pow.png -------------------------------------------------------------------------------- /images/doc-print-def.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-print-def.png -------------------------------------------------------------------------------- /images/doc-print.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/doc-print.png -------------------------------------------------------------------------------- /images/download-from-github.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/download-from-github.png -------------------------------------------------------------------------------- /images/four-cones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/four-cones.png -------------------------------------------------------------------------------- /images/framing-bias.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/framing-bias.png -------------------------------------------------------------------------------- /images/framing-effect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/framing-effect.png -------------------------------------------------------------------------------- /images/frontend.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/frontend.png -------------------------------------------------------------------------------- /images/george-boole-google-doodle-2015.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/george-boole-google-doodle-2015.gif -------------------------------------------------------------------------------- /images/george-boole-in-1864.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/george-boole-in-1864.png -------------------------------------------------------------------------------- /images/git-command-relationships.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/git-command-relationships.png -------------------------------------------------------------------------------- /images/git-time-machine-cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/git-time-machine-cover.png -------------------------------------------------------------------------------- /images/github-commit.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-commit.png -------------------------------------------------------------------------------- /images/github-confirm-merge.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-confirm-merge.png -------------------------------------------------------------------------------- /images/github-create-pull-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-create-pull-request.png -------------------------------------------------------------------------------- /images/github-fork.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-fork.png -------------------------------------------------------------------------------- /images/github-markdown-style.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-markdown-style.gif -------------------------------------------------------------------------------- /images/github-merged-pull-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-merged-pull-request.png -------------------------------------------------------------------------------- /images/github-new-branch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-new-branch.png -------------------------------------------------------------------------------- /images/github-open-pull-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-open-pull-request.png -------------------------------------------------------------------------------- /images/github-pull-request.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/github-pull-request.png -------------------------------------------------------------------------------- /images/google-homepage-1998.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/google-homepage-1998.png -------------------------------------------------------------------------------- /images/google-how-effectively.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/google-how-effectively.png -------------------------------------------------------------------------------- /images/google-prototype-1998.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/google-prototype-1998.png -------------------------------------------------------------------------------- /images/google-stackoverflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/google-stackoverflow.png -------------------------------------------------------------------------------- /images/guitar-tab.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/guitar-tab.gif -------------------------------------------------------------------------------- /images/hedy-lamarr-hero-getty.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/hedy-lamarr-hero-getty.jpg -------------------------------------------------------------------------------- /images/intro.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/intro.png -------------------------------------------------------------------------------- /images/iter-relationships.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/iter-relationships.gif -------------------------------------------------------------------------------- /images/jupyter-lab-launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/jupyter-lab-launcher.png -------------------------------------------------------------------------------- /images/jupyter-lab-terminal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/jupyter-lab-terminal.png -------------------------------------------------------------------------------- /images/learning-curve-spiral.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/learning-curve-spiral.gif -------------------------------------------------------------------------------- /images/learning-curve-spiral.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/learning-curve-spiral.png -------------------------------------------------------------------------------- /images/list-concepts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/list-concepts.png -------------------------------------------------------------------------------- /images/local-tutorial.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/local-tutorial.png -------------------------------------------------------------------------------- /images/operations@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/operations@2x.png -------------------------------------------------------------------------------- /images/python-containers-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-containers-2.png -------------------------------------------------------------------------------- /images/python-containers-final.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-containers-final.png -------------------------------------------------------------------------------- /images/python-containers.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-containers.jpg -------------------------------------------------------------------------------- /images/python-containers.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-containers.pdf -------------------------------------------------------------------------------- /images/python-containers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-containers.png -------------------------------------------------------------------------------- /images/python-leading-space.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/python-leading-space.png -------------------------------------------------------------------------------- /images/recursive-function-call.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/recursive-function-call.png -------------------------------------------------------------------------------- /images/redemo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/redemo.png -------------------------------------------------------------------------------- /images/regex-test.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/regex-test.gif -------------------------------------------------------------------------------- /images/regex101.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/regex101.gif -------------------------------------------------------------------------------- /images/rename-macos.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/rename-macos.png -------------------------------------------------------------------------------- /images/rotating-cube.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/rotating-cube.gif -------------------------------------------------------------------------------- /images/search-generated-by-sphinx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/search-generated-by-sphinx.png -------------------------------------------------------------------------------- /images/seflteaching-model.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/seflteaching-model.png -------------------------------------------------------------------------------- /images/split.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/split.png -------------------------------------------------------------------------------- /images/string-concept-table.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/string-concept-table.png -------------------------------------------------------------------------------- /images/string-concepts.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/string-concepts.png -------------------------------------------------------------------------------- /images/symbols.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/symbols.png -------------------------------------------------------------------------------- /images/sync-fork-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-1.png -------------------------------------------------------------------------------- /images/sync-fork-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-2.png -------------------------------------------------------------------------------- /images/sync-fork-3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-3.png -------------------------------------------------------------------------------- /images/sync-fork-4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-4.png -------------------------------------------------------------------------------- /images/sync-fork-5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-5.png -------------------------------------------------------------------------------- /images/sync-fork-6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-6.png -------------------------------------------------------------------------------- /images/sync-fork-7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/sync-fork-7.png -------------------------------------------------------------------------------- /images/three-cones.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/three-cones.png -------------------------------------------------------------------------------- /images/vscode-extensions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/vscode-extensions.png -------------------------------------------------------------------------------- /images/vscode-select-python-version1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/vscode-select-python-version1.png -------------------------------------------------------------------------------- /images/vscode-select-python-version2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/vscode-select-python-version2.png -------------------------------------------------------------------------------- /images/vscode-shell.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/vscode-shell.png -------------------------------------------------------------------------------- /images/vscodedemo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/images/vscodedemo.gif -------------------------------------------------------------------------------- /life-expectancy-china-1960-2016.txt: -------------------------------------------------------------------------------- 1 | 1960, 43.725 2 | 1961, 44.051 3 | 1962, 44.783 4 | 1963, 45.972 5 | 1964, 47.592 6 | 1965, 49.549 7 | 1966, 51.696 8 | 1967, 53.847 9 | 1968, 55.843 10 | 1969, 57.603 11 | 1970, 59.085 12 | 1971, 60.303 13 | 1972, 61.344 14 | 1973, 62.281 15 | 1974, 63.134 16 | 1975, 63.915 17 | 1976, 64.631 18 | 1977, 65.278 19 | 1978, 65.857 20 | 1979, 66.377 21 | 1980, 66.843 22 | 1981, 67.256 23 | 1982, 67.618 24 | 1983, 67.933 25 | 1984, 68.21 26 | 1985, 68.451 27 | 1986, 68.661 28 | 1987, 68.842 29 | 1988, 69.002 30 | 1989, 69.15 31 | 1990, 69.293 32 | 1991, 69.437 33 | 1992, 69.587 34 | 1993, 69.75 35 | 1994, 69.935 36 | 1995, 70.156 37 | 1996, 70.427 38 | 1997, 70.747 39 | 1998, 71.115 40 | 1999, 71.521 41 | 2000, 71.955 42 | 2001, 72.401 43 | 2002, 72.84 44 | 2003, 73.257 45 | 2004, 73.642 46 | 2005, 73.987 47 | 2006, 74.291 48 | 2007, 74.562 49 | 2008, 74.808 50 | 2009, 75.032 51 | 2010, 75.236 52 | 2011, 75.425 53 | 2012, 75.602 54 | 2013, 75.769 55 | 2014, 75.932 56 | 2015, 76.092 57 | 2016, 76.252 58 | -------------------------------------------------------------------------------- /markdown/00.cover.md: -------------------------------------------------------------------------------- 1 | 2 | # 自学是门手艺 3 | 4 | > One has no future if one couldn't teach themself[1]. 5 | 6 | **作者:李笑来** 7 | 8 | 特别感谢**霍炬**([@virushuo](https://github.com/virushuo))、**洪强宁**([@hongqn](https://github.com/hongqn)) 两位良师诤友在此书写作过程中给予我的巨大帮助! 9 | 10 | ```python 11 | # pseudo-code of selfteaching in Python 12 | 13 | def teach_yourself(anything): 14 | while not create(): 15 | learn() 16 | practice() 17 | return teach_yourself(another) 18 | 19 | teach_yourself(coding) 20 | ``` 21 | 22 | ## 目录 23 | 24 | > - [01.preface(**前言**)](01.preface.md) 25 | > - [02.proof-of-work(**如何证明你真的读过这本书?**)](02.proof-of-work.md) 26 | > - [Part.1.A.better.teachyourself(**为什么一定要掌握自学能力?**)](Part.1.A.better.teachyourself.md) 27 | > - [Part.1.B.why.start.from.learning.coding(**为什么把编程当作自学的入口?**)](Part.1.B.why.start.from.learning.coding.md) 28 | > - [Part.1.C.must.learn.sth.only.by.reading(**只靠阅读习得新技能**)](Part.1.C.must.learn.sth.only.by.reading.md) 29 | > - [Part.1.D.preparation.for.reading(**开始阅读前的一些准备**)](Part.1.D.preparation.for.reading.md) 30 | > - [Part.1.E.1.entrance(**入口**)](Part.1.E.1.entrance.md) 31 | > - [Part.1.E.2.values-and-their-operators(**值及其相应的运算**)](Part.1.E.2.values-and-their-operators.md) 32 | > - [Part.1.E.3.controlflow(**流程控制**)](Part.1.E.3.controlflow.md) 33 | > - [Part.1.E.4.functions(**函数**)](Part.1.E.4.functions.md) 34 | > - [Part.1.E.5.strings(**字符串**)](Part.1.E.5.strings.md) 35 | > - [Part.1.E.6.containers(**数据容器**)](Part.1.E.6.containers.md) 36 | > - [Part.1.E.7.files(**文件**)](Part.1.E.7.files.md) 37 | > - [Part.1.F.deal-with-forward-references(**如何从容应对含有过多 “过早引用” 的知识?**)](Part.1.F.deal-with-forward-references.md) 38 | > - [Part.1.G.The-Python-Tutorial-local(**官方教程:The Python Tutorial**)](Part.1.G.The-Python-Tutorial-local.md) 39 | > - [Part.2.A.clumsy-and-patience(**笨拙与耐心**)](Part.2.A.clumsy-and-patience.md) 40 | > - [Part.2.B.deliberate-practicing(**刻意练习**)](Part.2.B.deliberate-practicing.md) 41 | > - [Part.2.C.why-start-from-writing-functions(**为什么从函数开始?**)](Part.2.C.why-start-from-writing-functions.md) 42 | > - [Part.2.D.1-args(**关于参数(上)**)](Part.2.D.1-args.md) 43 | > - [Part.2.D.2-aargs(**关于参数(下)**)](Part.2.D.2-aargs.md) 44 | > - [Part.2.D.3-lambda(**化名与匿名**)](Part.2.D.3-lambda.md) 45 | > - [Part.2.D.4-recursion(**递归函数**)](Part.2.D.4-recursion.md) 46 | > - [Part.2.D.5-docstrings(**函数的文档**)](Part.2.D.5-docstrings.md) 47 | > - [Part.2.D.6-modules(**保存到文件的函数**)](Part.2.D.6-modules.md) 48 | > - [Part.2.D.7-tdd(**测试驱动的开发**)](Part.2.D.7-tdd.md) 49 | > - [Part.2.D.8-main(**可执行的 Python 文件**)](Part.2.D.8-main.md) 50 | > - [Part.2.E.deliberate-thinking(**刻意思考**)](Part.2.E.deliberate-thinking.md) 51 | > - [Part.3.A.conquering-difficulties(**战胜难点**)](Part.3.A.conquering-difficulties.md) 52 | > - [Part.3.B.1.classes-1(**类 —— 面向对象编程**)](Part.3.B.1.classes-1.md) 53 | > - [Part.3.B.2.classes-2(**类 —— Python 的实现**)](Part.3.B.2.classes-2.md) 54 | > - [Part.3.B.3.decorator-iterator-generator(**函数工具**)](Part.3.B.3.decorator-iterator-generator.md) 55 | > - [Part.3.B.4.regex(**正则表达式**)](Part.3.B.4.regex.md) 56 | > - [Part.3.B.5.bnf-ebnf-pebnf(**BNF 以及 EBNF**)](Part.3.B.5.bnf-ebnf-pebnf.md) 57 | > - [Part.3.C.breaking-good-and-bad(**拆解**)](Part.3.C.breaking-good-and-bad.md) 58 | > - [Part.3.D.indispensable-illusion(**刚需幻觉**)](Part.3.D.indispensable-illusion.md) 59 | > - [Part.3.E.to-be-thorough(**全面 —— 自学的境界**)](Part.3.E.to-be-thorough.md) 60 | > - [Part.3.F.social-selfteaching(**自学者的社交**)](Part.3.F.social-selfteaching.md) 61 | > - [Part.3.G.the-golden-age-and-google(**这是自学者的黄金时代**)](Part.3.G.the-golden-age-and-google.md) 62 | > - [Part.3.H.prevent-focus-drifting(**避免注意力漂移**)](Part.3.H.prevent-focus-drifting.md) 63 | > - [Q.good-communiation(**如何成为优秀沟通者**)](Q.good-communiation.md) 64 | > - [R.finale(**自学者的终点**)](R.finale.md) 65 | > - [S.whats-next(**下一步干什么?**)](S.whats-next.md) 66 | > - [T-appendix.editor.vscode(**Visual Studio Code 的安装与配置**)](T-appendix.editor.vscode.md) 67 | > - [T-appendix.git-introduction(**Git 简介**)](T-appendix.git-introduction.md) 68 | > - [T-appendix.jupyter-installation-and-setup(**Jupyterlab 的安装与配置**)](T-appendix.jupyter-installation-and-setup.md) 69 | > - [T-appendix.symbols(**这些符号都代表什么?**)](T-appendix.symbols.md) 70 | 71 | 本书的版权协议为 [CC-BY-NC-ND license](https://creativecommons.org/licenses/by-nc-nd/3.0/deed.zh)。 72 | 73 | ![CC-BY-NC-ND](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/CC-BY-NC-ND.png?raw=true) 74 | 75 | ----- 76 | **脚注** 77 | 78 | [1]:['Themselves' or 'themself'?-- Oxford Dictionary](https://en.oxforddictionaries.com/usage/themselves-or-themself) 79 | 80 | ↑Back to Content↑ 81 | -------------------------------------------------------------------------------- /markdown/01.preface.md: -------------------------------------------------------------------------------- 1 | 2 | # 前言 3 | 4 | 想写一本关于自学能力的书,还真的不是一天两天的事,所以肯定不是心血来潮。 5 | 6 | 等我快把初稿框架搭完,跟霍炬说起我正在写的内容时,霍炬说: 7 | 8 | > 你还记得吗,你第一次背个包来我家的时候,咱们聊的就是咋写本有意思的编程书…… 9 | 10 | 我说: 11 | 12 | > 真是呢!十三年就这么过去了…… 13 | 14 | 不过,这次真的写了。写出来的其实并不是,或者说,并不仅仅是 “一本编程书”。 15 | 16 | 这本 “书” 是近些年我一直在做却没做完整的事情,讲清楚 “学习学习再学习”: 17 | 18 | > 学会学习之后再去学习…… 19 | 20 | 只不过,这一次我阐述地更具体 —— 不是 “学会学习”,而是 “学会自学” —— 这一点点的变化,让十多年前没写顺的东西,终于在这一次迎刃而解,自成体系。 21 | 22 | > 以前,我在写作课里讲,写好的前提就是 “Narrow down your topic” —— 把话题范围缩小缩小再缩小…… 这次算是给读者一个活生生的实例了罢。 23 | 24 | 自学能力,对每个个体来说,是这个变化频率和变化幅度都在不断加大的时代里最具价值的能力。具备这个能力,不一定能直接增加一个人的幸福感(虽然实际上常常确实能),但它一定会缓解甚至消除一个人的焦虑 —— 若是在一个以肉眼可见的方式变化着的环境里生存,却心知肚明自己已然原地踏步许久,自己正在被这个时代甩在身后,谁能不焦虑呢? 25 | 26 | 实际上,这些年来我写的书,都是关于学习的,无论是《[把时间当作朋友](https://github.com/xiaolai/time-as-a-friend)》,还是《通往财富自由之路》,甚至《韭菜的自我修养》,你去看就知道,背后都是同样的目标:学习、进步 —— 甚至**进化**。 27 | 28 | 这一次的《自学是门手艺》,首先,可以看作是之前内容的 “实践版”: 29 | 30 | > 完成这本书的内容,起码会习得一个新技能:编程。 31 | 32 | 更为重要的是,可以把《自学是门手艺》当作之前内容的 “升级版”: 33 | 34 | > 自学能力,是持续学习持续成长的发动机…… 35 | 36 | 仔细观察整个人群,你就会发现一个惊人且惊悚的事实: 37 | 38 | > **至少有 99% 的人终生都没有掌握自学能力!** 39 | 40 | 其实这个数字根本不夸张。根据 2017 年的统计数据,从 1977 年到 2017 年,40 年间全国大学录取人数总计为 1.15 亿左右(11518.2 万),占全国人口数量的 10% 不到,另外,这其中一半以上是专科生…… 你觉得那些 4% 左右的本科毕业生中,带着自学能力走入社会的比例是多少?不夸张地讲,我觉得 1% 都是很高的比例了 —— 所以,前面提到的 99% 都是很客气的说法。 41 | 42 | 绝大多数人,终其一生都没有自学过什么。他们也不是没学过,也不是没辛苦过,但事实却是:他们在有人教、有人带、有人逼的情况下都没真学明白那些基础知识…… 更可怕的是,他们学的那些东西中,绝大多数终其一生只有一个用处:考试。于是,考试过后,那些东西就 “考过即弃” 了…… 不得不承认,应试教育的确是磨灭自学能力的最有效方法。 43 | 44 | 在随后的生活里,尽管能意识到自己应该学点什么,常有 “要是我也会这个东西就好了” 的想法,但基本上百分之百以无奈结束 —— 再也没有人教、再也没有人带、再也没有人逼…… 于是,每次 “决心重新做人” 都默默地改成 “继续做人” 而后逢年过节再次许愿 “重新做人”…… 45 | 46 | 这是有趣而又尴尬的真相: 47 | 48 | > 没有不学习的人。 49 | 50 | 你仔细观察就知道了,就算被你认为不学无术的人,其实也在学习,只不过,他们的选择不同,他们想学的是投机取巧,并天天琢磨怎样才能更好地投机取巧…… 51 | 52 | 但他们不是最倒霉的人。最倒霉的人是那种人,也 “认真学了”,可总是最终落得个越来越焦虑的下场…… 53 | 经常有一些人指责另外一些人 “贩卖焦虑” —— 根据我的观察,这种指责的肤浅在于,焦虑不是被卖方贩卖的产品,焦虑其实是买方长期自行积累的结果。 54 | 55 | **别人无法贩卖给你焦虑,是你自己焦虑** —— 是你自己在为自己不断积累越来越多的焦虑…… 56 | 57 | 然而,又有谁不想解决掉焦虑呢?又有谁不想马上解决掉焦虑呢? 58 | 59 | 于是,你焦虑,你就要找解决方案。而焦虑的你找到的解决方案,就是花个钱买本书,报个班,找个老师,上个课…… 这能说是别人贩卖焦虑给你吗? 60 | 61 | 自学能力强的人,并非不花钱,甚至他们花的钱可能更多。他们也花钱买书,而且买更多的书;他们也可能花钱上课,而且要上就上最好的课、最好的班;他们更经常费尽周折找到恰当的人咨询、求教、探讨 —— 所以,事实上,他们更可能花了更多的钱…… 62 | 63 | 但自学能力强的人不焦虑,起码他们不会因为学习以及学习过程而焦虑 —— 这是重大差别。 64 | 65 | 而焦虑的大多数,并不是因为别人贩卖焦虑给他们,他们才 “拥有” 那些焦虑 —— 他们一直在焦虑,并且越来越焦虑…… 66 | 67 | 为什么呢?总也学不会、学不好,换做是你,你不焦虑吗?! 68 | 69 | 生活质量就是这样一点一点被消磨掉的 —— 最消耗生活质量的东西,就是焦虑。 70 | 71 | 我相信,若是《自学是门手艺》这本书真的有用,它的重要用处之一就是能够缓解你的焦虑,让你明白,首先焦虑没用,其次,有办法也有途径让你摆脱过往一事无成的状况,逐步产生积累,并且逐步体会到那积累的作用,甚至最后还能感觉到更多积累带来的加速度…… 到那时候,焦虑就是 “别人的事情” 了。 72 | 73 | 自学没有什么 “秘诀”。**它是一门手艺**,并且,严格意义上来讲,它**只是**一门手艺。 74 | 75 | 手艺的特点就是**无需天分**。手艺的特点就是**熟练程度决定一切**。从这一点上来看,自学这门手艺和擀饺子皮没什么区别 —— 就那点事,刚开始谁都笨手笨脚,但熟练了之后,就那么回事…… 而已。 76 | 77 | 做什么事都有技巧,这不可否认。 78 | 79 | 自学当然也有技巧…… 不过,请做好思想准备: 80 | 81 | > 这儿的空间,**没什么新鲜**…… 82 | 83 | —— 这是崔健一首歌里的歌词片段,但放在这里竟然非常恰当到位。 84 | 85 | **一切与自学相关的技巧都是老生常谈**。 86 | 87 | 中国人说,熟能生巧;老外说,Practice makes perfect —— 你看,与自学相关的技巧,干脆不分国界…… 88 | 89 | —— 因为这事人类从起点开始就没变过 —— 每代人都有足够多的人在自学这件事上挣扎…… 有成的有不成的;成的之中有大成有小成…… 可有一件事同样不变:留下的文字、留下的信息,都是大成或者小成之人留下的,不成的人不声不响就销声匿迹。 90 | 91 | 并且,从各国历史上来看,自学技巧这个话题从未涉及到政治,无论是在东方还是西方都是如此。结果就是,在自学能力这个小领域中,留下并流传下来的信息,几乎从未被审查,从未被摧毁,从未被侵犯,从未被扭曲 —— 真的是个特别罕见的 “纯净的领域” —— 这真的是整个人类不可想像之意外好运。 92 | 93 | 这就是为什么一切的自学技巧到最后肯定是老生常谈的原因。 94 | 95 | 大部分年轻人讨厌老生常谈。 96 | 97 | 但这还真的是被误导的结果。年轻人被什么误导了呢? 98 | 99 | 每一代人都是新鲜出生,每一代人出生时都在同一水准…… 随着时间的推移,总是庸者占绝大多数,这个 “绝大多数” 不是 51%,不是 70%,而是 99%!—— 年轻人吃亏就吃在没把这个现象考虑进来。 100 | 101 | 也就是说,虽然有用的道理在不断地传播,可终究还是 99% 的人做不到做不好,于是: 102 | 103 | > 讲大道理的更可能是庸者、失败者,而不是成功者。 104 | 105 | 人类有很多天赋。就好像我反复提到的那样,“就算不懂也会用” 是人类的特长。同样的道理,人类在这方面同样擅长: 106 | 107 | > 无论自己什么样,在 “判断别人到底是不是真的很成功” 上,基本上有 99% 的把握…… 108 | 109 | 所以,十岁不到的时候,绝大多数小朋友就 “看穿” 了父母,后来再 “看穿” 了老师…… 发现他们整天说的都是他们自己做不到的事情…… 于是误以为自己 “看穿” 了整个世界。 110 | 111 | 那时候小朋友们还没学、或者没学好概率这个重要知识,于是,他们并不知道那只不过是 99% 的情况,而且更不知道 “**因素的重要性与它所占的比例常常全无正相关**”,所以当然不知道那自己尚未见到的 `1%` 才可能是最重要的…… 112 | 113 | 于是,99% 的小朋友们一不小心就把自己 “搭了进去”: 114 | 115 | > 不仅讨厌老生常谈,而且偏要对着干,干着干着就把自己变成了另外一个属于那 99% 的另外一个老生…… 116 | 117 | 这是 99% 的人终其一生的生动写照。 118 | 119 | 做 `1%` 很难吗?真的很简单,有时仅仅一条就可能奏效: 120 | 121 | > **在自学这件事上,重视一切老生常谈……** 122 | 123 | 很难吗?不难,只不过是一个 “开关” 而已。 124 | 125 | 当我动手写这本 “书” 的时候,是 47 岁那年(2019)的春节前 —— 显然,这个时候我也早就是一位 “老生” 了…… 并且,这些道理我已经前后讲了二十年!算是 “常谈” 甚至 “长谈” 了罢…… 126 | 127 | 开始在新东方教书那年,我 28 岁;用之前那一点三脚猫的编程能力辅助着去写《TOEFL 核心词汇 21 天突破》是 2003 年;后来写《[把时间当作朋友](https://github.com/xiaolai/time-as-a-friend)》是 2007 年,这本书的印刷版出版发行是在 2009 年;再后来陆续写了很多内容,包括没有纸质版发行只有在线版的《人人都能用英语》(2013);以及因为在罗振宇的得到 App 上开专栏,把之前写过的《学习学习再学习》重构且扩充而出版的《通往财富自由之路》(2017);甚至连《韭菜的自我修养》(2018)都是讲思考、学习、和认知升级的…… 128 | 129 | 说来说去,就那些事 —— **没什么新鲜**。 130 | 131 | 这中间也有很多写了却没写完,或者因为写得自己不满意扔在柜子里的东西,比如《人人都是工程师》(2016)—— 哈!我就是这么坚韧,有了目标就会死不放弃…… 3 年后的今天,我终于用那个时候完全想不到的方式完成了当时的目标,并且,做到了很多 3 年前自己都完全想象不到的事情。 132 | 133 | 在写当前这本《自学是门手艺》的过程中,我从一开始就干脆没想给读者带来什么 “新鲜” 的或者 “前所未见” 的自学技巧 —— 因为真的就没有,根本就没有什么新鲜的自学技巧…… 没有,真的没有 —— 至少,我自己这么久了还是真的没见识过。 134 | 135 | 然而,我算是最终能做到的人。知道、得到、做到之间,均各不相同。 136 | 137 | 二十年前,在拥挤的课堂里坐在台下听我讲课的小朋友们,绝大多数在当时应该没有想到他们遇到了这样一个人 —— 二十年后,刚认识我的人也不会自动知道我是这样的人。 138 | 139 | 但是,这些年里,看到我在一点一点进步、从未原地踏步的人很多很多…… 我猜,所谓的 “榜样”,也不过如此了罢。 140 | 141 | 不夸张地讲,这可能是当前世界上**最硬核的鸡汤书**了 —— 因为,虽然它就是鸡汤(李笑来自认就是个鸡汤作者),但它不是 “只是拿话糊弄你” 那种,也不是 “只不过是善意的鼓励” 那种,它是那种 “教会你人生最重要的技能” 的鸡汤,并且还不仅仅只有一种技能,起码两个:“自学能力” 和 “编程能力”…… 而这两个能力中的无论哪一种,都是能确定地提高读者未来收入的技能,对,就是 `100%` 地确定 —— 有个会计专业的人求职的时候说 “我还会编程” 且还能拿出作品,你看看他可不可能找不到工作?你看看他是不是能薪水更高? 142 | 143 | `#!` —— 这是个程序员能看懂的梗。 144 | 145 | 关键在于,这个老生不是说说而已的老生,他是能够**做到**的人: 146 | 147 | > - 一个末流大学的会计专业毕业的人不得已去做了销售; 148 | > - 这个销售后来去国内最大的课外辅导机构当了 7 年 TOEFL/GRE/GMAT 老师; 149 | > - 这个英语老师后来同时成了很多畅销书、长销书的作者; 150 | > - 这个作者后来居然成了著名天使投资人; 151 | > - 这个投资人后来竟然写了本关于编程入门的书籍; 152 | > - 这本 “书” 最终竟然还是一个完整的产品,不仅仅是 “一本书”…… 153 | 154 | 然而呢? 155 | 156 | —— 然而,即便是这样的老生,也讲不出什么新鲜道理。 157 | 158 | 因为啊,历史上留下来的所有关于自学的技巧,都是人类史上最聪明的人留下来的 —— 你我这样的人,照做就可以了…… 现在你明白怎么回事了吧? 159 | 160 | **记住罢** —— 161 | 162 | > **千万不要一不小心就把自己搭进去……** 163 | 164 |

李笑来

165 |

初稿完成于 2019227

166 | 167 | -------------------------------------------------------------------------------- /markdown/02.proof-of-work.md: -------------------------------------------------------------------------------- 1 | 2 | # 如何证明你真的读过这本书? 3 | 4 | ## 積ん読 5 | 6 | 日语里有个很好玩的词,“**積ん読**”([tsundoku](https://en.wikipedia.org/wiki/Tsundoku)): 7 | 8 | > 指那些买回来堆在那里还没读过的(甚至后来干脆不看了的)书…… 9 | 10 | 细想想,每个人都有很多很多 “積ん読”。小时候我们拿回家的教科书中就有相当一部分,其实就是 “積ん読”,虽然那时候掏钱买书的是父母,不仔细看、或者干脆不看的时候,也知道自己在偷懒…… 再后来就是 “主动犯罪” 了 —— 比如,很多人买到手里的英语词汇书是根本就没有翻到过第二个列表的,乃至于过去我常常开玩笑说,中国学生都认识一个单词,*abandon*,不是吗?这个单词是很多很多人 “决心重新做人” 而后 “就这样罢” 的铁板钉钉的见证者。 11 | 12 | 在没有电子书的时代,印刷版书籍多少还有一点 “装饰品” 功用,可是到了电子书时代,谁知道你的设备里有多少付费书籍呢?攒下那么多,其实并没有炫耀的地方,给谁看呢?据说,Kindle 的后台数据里可以看到清楚的 “打开率”,大抵上也是在 ¼ ~ ⅓ 之间,也就是说,差不多有 ⅔ ~ ¾ 的电子书籍被购买下载之后,从来就没有被打开过。 13 | 14 | 如此看来,付费之后并不阅读,只能欺骗一个对象了:自己。跟心理学家们之前想象的不同,我认为人们通常是不会欺骗自己的,至少很难 “故意欺骗自己”。所以,对于 “买了之后坚决不读” 这个现象,我不认为 “给自己虚妄的满足感” 是最好的解释。 15 | 16 | 更朴素一点,更接近真相的解释是: 17 | 18 | > 那百分之七八十的人,其实是想着给自己一个希望…… 19 | 20 | —— 等我有空了一定看。嗯。 21 | 22 | 说来好笑,其实每个人共同拥有的目标之一是这样的: 23 | 24 | > 成为前百分之二十的少数人…… 25 | 26 | 然而,PK 掉百分之七八十的人的方法真的很简单很简单啊: 27 | 28 | > 把买来的书都真真切切地认真读过就可以了。 29 | 30 | 这实在是太简单了罢?!可是…… 我知道你刚刚那个没出息的闪念: 31 | 32 | > 那我少买书甚至不买书不就可以了吗? 33 | 34 | 你自己都知道这是荒谬的,却忍不住为你的小聪明得意 —— 其实吧,幸亏有你们在,否则我们怎么混进前百分之二十呢? 35 | 36 | ## PoW 37 | 38 | 比特币这个地球上第一个真正被证明为可行的区块链应用中有一个特别重要的概念,叫做 “**工作证明**”(Proof of Work)—— 你干活了就是干活了,你没干活就是没干活,你的工作是可被证明的…… 39 | 40 | 借用这个思路,我设计了个方法,让你有办法证明自己就是看过这本书,就是读完了这本书 —— 你能向自己也向别人证明自己曾经的工作…… 是不是挺好? 41 | 42 | 证明的方法是使用 [github.com](https://github.com) 这个网站以及版本控制工具 **git**。 43 | 44 | ## 具体步骤 45 | 46 | 请按照以下步骤操作: 47 | 48 | > 1. 注册 [github.com](https://github.com) 帐号 —— 无论如何你都必须有 github 账户; 49 | > 2. 使用浏览器访问 [https://github.com/selfteaching/the-craft-of-selfteaching](https://github.com/selfteaching/the-craft-of-selfteaching); 50 | > 3. 在页面右上部找到 “Fork” 按钮,将该仓库 Fork 到你自己的账户中; 51 | > 4. 使用 `git clone` 命令或者使用 [Desktop for Github](https://desktop.github.com/) 将 [the craft of selfteaching](https://github.com/selfteaching/the-craft-of-selfteaching) 这个你 Fork 过来的仓库克隆到本地; 52 | > 5. 按照 [Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.md) 的说明在本地搭建好 Jupyterlab —— 如果在 Jupyterlab 中浏览本书的话,其中的所有代码都是可以 “当场执行” 的,并且,你还可以直接改着玩…… 53 | > 6. 在阅读过程中,可以不断通过修改文章中的代码作为练习 —— 这样做的结果就是已阅读过的文件会发生变化…… 每读完一章,甚至时时刻刻,你都可以通过 `git commit` 命令向你自己 Fork 过来的仓库提交变化 —— 这就是你的阅读工作证明; 54 | > 7. 仓库里有一个目录,`my-notes`,你可以把你在学习过程中写的笔记放在那里; 55 | > 8. 仓库里还有另外一个目录,`from-readers`;那是用来收集读者反馈的 —— 将来你可以写一篇《我的自学之路》,放在这个目录里,单独创建一个分支,而后提交 `pull request`,接受其他读者投票,若是达到一定的赞同率,那么你的文章就会被收录到主仓库中被更多人看到,激励更多的人像你一样走上自学之路…… 56 | 57 | 当然,为了这么做,你还要多学一样反正你早晚都必须学会的东西,Git —— 请参阅附录《[Git 入门](T-appendix.git-introduction.md)》。 58 | 59 | 时间就是这样,我们没办法糊弄它。而有了 git 这样的工具之后,我们在什么时候做了什么样的工作,是很容易证明的 —— 这对我们来说真是天大的好事。 60 | 61 | ## 如何使用 Pull Request 为这本书校对 62 | 63 | 另外,在你阅读的过程中,发现有错别字啊、代码错误啊,甚至有 “更好的表述” 等等,都可以通过 `pull request` 来帮我改进 —— 这也是一种 “工作证明”。 64 | 65 | (1) 使用浏览器访问 https://github.com/selfteaching/the-craft-of-selfteaching 66 | 67 | (2) 点击右上角的 “Fork 按钮”,将该仓库 Fork 到你的 Github 账户中 68 | 69 | ![](images/github-fork.png?raw=true) 70 | 71 | (3) 创建一个新分支,可以取名为 `from-`,比如,`by git.basic.tutorial`;之后点击 Create Branch 建立新分支。 72 | 73 | ![](images/github-new-branch.png?raw=true) 74 | 75 | (4) 在新分支下进行修改某个文件,而后提交 —— 提交前不要嫌麻烦,一定要在 Comment 中写清楚修改说明: 76 | 77 | ![](images/github-commit.png?raw=true) 78 | 79 | 以上示例图片中是修改了 README.md 文件 —— 事实上,你应该提交的是的确有必要的校对。 80 | 81 | 另外,**请注意**:在创建分支之前,要将你的 Fork 更新到最新版。具体操作方法见下一节《如何在 Github 网站上将自己的 Fork 与原仓库同步》。 82 | 83 | (5) 在页面顶部选择 Pull request 标签: 84 | 85 | ![](images/github-pull-request.png?raw=true) 86 | 87 | 而后点击 `Compare & pull request` 按钮 —— 如果看不到这个按钮,那就点击下面刚刚修改文件的链接,如上图中的 “Update README.md”(这是你刚刚提交修改时所填写的标题)。 88 | 89 | ![](images/github-open-pull-request.png?raw=true) 90 | 91 | 确认无误之后,点击 `Create pull request` 按钮。 92 | 93 | ![](images/github-create-pull-request.png?raw=true) 94 | 95 | (6) 随后,Github 用户 [@xiaolai](https://github.com/xiaolai) —— 就是我,即,the-craft-of-selfteaching 这个仓库的所有者,会被通知有人提交了 Pull request,我会看到: 96 | 97 | ![](images/github-confirm-merge.png?raw=true) 98 | 99 | 在我确认这个 Pull request 修改是正确的、可接受的之后,我就会按 `Merge pull request` 按钮 —— 如此这般,一个修正就由你我共同完成了。 100 | 101 | ![](images/github-merged-pull-request.png?raw=true) 102 | 103 | **注意** 104 | 105 | 提交 Pull request 的时候,最佳策略如下: 106 | 107 | > * 提交 Pull request 之前,必须先将你的 Fork 的 master 与原仓库同步到最新; 108 | > * 从 master 创建 **新的 branch** 进行增补、修改等操作; 109 | > * 尽量每次只提交一个小修改; 110 | > * 提交时尽量简短且清楚地说明修改原因; 111 | > * 耐心等待回复。 112 | 113 | 当自己的 Fork 过来的仓库已经被你在本地 “玩残” 了的时候,它千万不能被当作用来提交 Pull request 的版本。自己本地怎么玩都无所谓,但需要向别人提交 Pull request 的时候,必须重新弄一个当前最新版本到本地,而后再在其基础上修改。 114 | 115 | ## 如何在 Github 网站上将自己的 Fork 与原仓库同步 116 | 117 | (1) 在你的 Fork 页面中如下图所示,点击 `Compare` 链接: 118 | 119 | ![](images/sync-fork-1.png?raw=true) 120 | 121 | (2) 将 `base repository` 更改成当前自己的 Fork,在图示中即为 `gitbasictutorial/the-craft-of-selfteaching`: 122 | 123 | ![](images/sync-fork-2.png?raw=true) 124 | 125 | (3) 这时候,页面会显示 `There isn't anything to compare.`,因为你在比较 “自己” 和 “自己”。点击 `compare across forks` 链接: 126 | 127 | ![](images/sync-fork-3.png?raw=true) 128 | 129 | (4) 将 `head repository` 更改成 Upstream Repository(即,上游仓库),在图示中即为 `selfteaching/the-craft-of-selfteaching`: 130 | 131 | ![](images/sync-fork-4.png?raw=true) 132 | 133 | (5) 稍等片刻,你会看到比较结果;而后你可以创建一个 Pull request —— 这是一个由你自己向你自己的 Fork 仓库提交的 Pull request: 134 | 135 | ![](images/sync-fork-5.png?raw=true) 136 | 137 | (6) 而后你在 `Pull requests` 标签页里会看到你刚刚提交的 Pull request: 138 | 139 | ![](images/sync-fork-6.png?raw=true) 140 | 141 | (7) 同意并合并之后的结果是,你的 Fork 与上游仓库同步完成了: 142 | 143 | ![](images/sync-fork-7.png?raw=true) 144 | 145 | 当然,有时会出现一些你无法解决的问题,那么,还有一个最后的方法: 146 | 147 | > 将你的 Fork 删除,而后重新到 https://github.com/selfteaching/the-craft-of-selfteaching 页面按一次 `Fork` 按钮…… 148 | 149 | ## 如何使用 github 记录自己的学习过程 150 | 151 | 你可以在本地建立一个分支(branch),例如,取名为 `study`: 152 | 153 | ```bash 154 | git branch study 155 | git checkout study 156 | ``` 157 | 158 | 如此这般之后,你在本地工作目录中所做的任何修改,都可以提交到 `study` 这个分支之中。 159 | 160 | 你每次在 Jupyterlab 中浏览 `ipynb` 文件,按 `^ + Enter` 执行 code cell 中的代码的时候,该文件都会发生一些变化;你也可以随意修改文件中的任何地方,比如,添加一个 code cell,将某段代码从头至尾 “敲” 一遍;也可以修改某个 code cell 中的代码看看执行结果有什么不同;还可以添加或者修改任何 markdown cell —— 就当自己做笔记了…… 161 | 162 | 总而言之,当你阅读完某一章节并如上所说那样做了一些改动之后,那个 `ipynb` 文件就发生了一些变化。于是,你就可以执行以下命令: 163 | 164 | ```bash 165 | git add . 166 | git commit -am 'my study result' 167 | git push 168 | ``` 169 | 170 | 如此这般,在 `study` 这个分支中就记录着你的学习轨迹。 171 | 172 | 当然,如果在这过程中,你发现本书自身有需要校对的地方,那么,你需要切换到 `master` 分支,执行以下命令: 173 | 174 | ```bash 175 | git checkout master 176 | git pull 177 | ``` 178 | 179 | 而后再修改,进而按照上一节的方法提交 Pull request。 180 | 181 | 未来,在 [https://github.com/selfteaching](https://github.com/selfteaching) 下我会专门设置一个 repo,用来自动扫描 github 上本书的学习记录 —— 这种记录在过往的书籍当中是不可能存在的,然而,现在却可以了。在我看来,将来这种记录的作用甚至有可能比 “学历” 还要重要。 182 | -------------------------------------------------------------------------------- /markdown/Part.1.B.why.start.from.learning.coding.md: -------------------------------------------------------------------------------- 1 | 2 | # 为什么把编程当作自学的入口? 3 | 4 | 很多人误以为 “编程” 是很难的事情。 5 | 6 | …… 实则不然 —— 这恰恰是我们选择 “编程” 作为自学的第一个 “执行项目” 的原因。 7 | 8 | 一本关于自学能力的书,若是真的能够起到作用,那么它就必须让读者在读之前和读之后不一样 —— 比如,之前可能没有自学能力,或者自学能力很差,之后就有了一定的自学能力…… 9 | 10 | 然而,这很难。不但对读者来说很难,对作者来说更难 —— 我当过那么多年被学生高度评价的老师,出版过若干本畅销且长销的书籍,所以更是清楚地知道例子的重要性。 11 | 12 | 道理当然很重要;可是,在传递道理的时候,例子相对来看好像更重要。 13 | 14 | 同样的道理,例子不准,人就可能会理解错;例子不精彩,人就可能听不进去;例子居然可以令人震惊,那就可以做到让听众、让读者 “永生不忘”。 15 | 16 | 许多年前,有位后来在美国读书已经博士毕业了的学生来信,大意是说: 17 | 18 | > 好多年前,我在新东方上课,听您讲,人学习就好像是动物进化一样…… 很多人很早就开始停止了进化,本质上跟猴子没啥区别。 19 | > 20 | > 那段类比好长,我记不太清楚细节了…… 可是,当时我是出了一身汗的,因为我忽然觉得自己是一只猴子。可是,突然之间,我不想继续做猴子,更不想一直做猴子! 21 | > 22 | > 从那之后,我好像变了一个人似的…… 现在我已经博士毕业了,觉得应该写封信告诉您,我不再是猴子了,最起码是大猩猩,而且我保证,我会一直进化。 23 | > 24 | > …… 25 | 26 | 所以啊,在我看来,写书讲课之前,最重要的工作,也是做得最多的事情,其实就是 “找到好例子” —— 那即意味着说,先要找到很多很多恰当合适的例子,而后再通过反复比较试验,挑出那个效果最好的例子。了解了这一点,将来你准备任何演讲,都会不由自主地多花一点时间在这方面,效果肯定比 “把幻灯片做得更花哨一些” 要好太多了罢? 27 | 28 | 后来,我选中了一个例子:“**自学编程**” —— “*尽量只通过阅读学会编程*”。 29 | 30 | ## (一) 31 | 32 | 选择它的理由,首先就在于: 33 | 34 | > 事实证明,**它就是无论是谁都能学会的** —— 千万别不信。 35 | 36 | 它老少皆宜 —— 也就是说,“只要你愿意”,根本没有年龄差异。十二岁的孩子可以学;十八岁的大学生可以学;在职工作人员可以学…… 就算你已经退休了,想学就能学,谁也拦不住你。 37 | 38 | 它也不分性别,男性可以学,女性同样可以学,性别差异在这里完全不存在。 39 | 40 | 它也不分国界,更没有区域差异 —— 互联网的恩惠在于,你在北京、纽约也好,老头沟、门头沟也罢,在这个领域里同样完全没有任何具体差异。 41 | 42 | 尤其是在中国。现状是,中国的人口密度极高,优质教育资源的确就是稀缺…… 但在计算机科学领域,所有的所谓 “优质教育资源” 事实上完全没有任何独特的竞争力 —— 编程领域,实际上是当今世上极为罕见的 “**教育机会公平之地**”。又不仅在中国如此,事实上,在全球范围内也都是如此。 43 | 44 | ## (二) 45 | 46 | 编程作为 “讲解如何习得自学能力的例子”,实在是太好了。 47 | 48 | 首先,编程这个东西反正要自学 —— 不信你问问计算机专业的人,他们会如实告诉你的,学校里确实也教,但说实话都教得不太好…… 49 | 50 | 其次,编程这个东西最适合 “仅靠阅读自学” —— 这个领域发展很快,到最后,新东西出来的时候,没有老师存在,任由你是谁,都只能去阅读 “官方文档”,只此一条路。 51 | 52 | 然后,也是最重要的一条,别管是不是很多人觉得编程是很难的东西,事实上它就是每个人都应该具备的技能。 53 | 54 | 许多年前,不识字,被称为文盲…… 55 | 56 | 后来,人们反应过来了,不识英文,也是文盲,因为科学文献的主导语言是英文,读不懂英文,什么都吃不上热乎的;等菜好不容易端上来了吧,早就凉了不说,味道都常常会变…… 57 | 58 | 再后来,不懂基本计算机操作技能的,也算是文盲,因为他们无论做什么事情,效率都太低下了,明明可以用快捷键一下子完成的事情,却非要手动大量重复…… 59 | 60 | 到了最近,不懂数据分析的,也开始算作文盲了。许多年前人们惊呼信息时代来了的时候,其实暂时体会不到什么太多的不同。然而,许多年过去,互联网上的格式化数据越来越多,不仅如此,实时产出的格式化数据也越来越多,于是,数据分析不仅成了必备的能力,而且早就开始直接影响一个人的薪资水平。 61 | 62 | 你作为一个个体,每天都在产生各种各样的数据,然后时时刻刻都在被别人使用着、分析着…… 然而你自己却全然没有数据分析能力,甚至不知道这事很重要,是不是感觉很可怕?你看看周边那么多人,有多大的比例想过这事?反正那些天天看机器算法生成的信息流的人好像就是全然不在意自己正在被支配…… 63 | 64 | 怎么办?学呗,学点编程罢 —— 巧了,*这还真是个正常人都能学会的技能*。 65 | 66 | ## (三) 67 | 68 | 编程作为 “讲解如何习得自学能力的例子” 最好的地方在于,这个领域的知识结构,最接近每个人所面对的人生中的知识结构。 69 | 70 | 这是什么意思呢? 71 | 72 | 编程入门的门槛之所以高,有个比较特殊的原因: 73 | 74 | > **它的知识点结构不是线性的**。 75 | 76 | 我们在中小学里所遇到的教科书,其中每个章节所涉及到的知识点之间,全都是线性关联。第一章学好了,就有基础学第二章;在第二章的概念不会出现在第一章之中…… 77 | 78 | 很遗憾,编程所涉及到的知识点没办法这样组织 —— 就是不行。编程教材之所以难以读懂,就是因为它的各章中的知识点结构不是线性排列的。你经常在某一章读到不知道后面第几章才可能讲解清楚的概念。 79 | 80 | 比如,几乎所有的 Python 编程书籍上来就举个例子: 81 | 82 | ```python 83 | print('Hello, world!') 84 | ``` 85 | 86 | 姑且不管这个例子是否意义非凡或者意义莫名,关键在于,`print()` 是个函数,而函数这个概念,不可能一上来就讲清楚,只能在后面若干章之后才开始讲解…… 87 | 88 | > 想要理解当前的知识点,需要依赖对以后才能开始学习的某个甚至多个知识点的深入了解…… 89 | 90 | 这种现象,可以借用一个专门的英文概念,叫做 “**Forward References**” —— 原本是计算机领域里的一个[术语](https://en.wikipedia.org/wiki/Forward_declaration)。为了配合当前的语境,姑且把它翻译为 “**过早引用**” 罢,或者 “**前置引用**” 也行。 91 | 92 | 学校里的课本,都很严谨 —— 任何概念,未经声明就禁止使用。所以,学完一章,就能学下一章;跳到某一章遇到不熟悉的概念,往前翻肯定能找到…… 93 | 94 | 在学校里习惯了这种知识体系的人,离开学校之后马上抓瞎 —— **社会的知识结构不仅不是这样的,而且*几乎全都不是*这样的**。工作中、生活里,充满了各式各样的 “*过早引用*”。为什么总是要到多年以后你才明白父母曾经说过的话那么有道理?为什么总要到孩子已经长大之后才反应过来当初自己对孩子做错过很多事情?为什么在自己成为领导之前总是以为他们只不过是在忽悠你?为什么那么多人创业失败了之后才反应过来当初投资人提醒的一些观念其实是千真万确的?—— 因为很多概念很多观念是 “过早引用”,在当时就是非常难以理解…… 95 | 96 | 自学编程在这方面的好处在于,在自学的过程中,其实你相当于过了一遍 “模拟人生” —— 于是,面对同样的 “*过早引用*”,你不会觉得那么莫名其妙,你有一套你早已在 “模拟人生” 中练就的方法论去应对。 97 | 98 | ## (四) 99 | 100 | 另外一个把编程作为 “讲解如何习得自学能力的例子” 最好的地方在于,你在这个过程中将不得不习得英语 —— 起码是英文阅读能力,它能让你在不知不觉中 “脱盲”。 101 | 102 | 学编程中最重要的活动就是 “阅读官方文档”。学 Python 更是如此。Python 有很多非常优秀的地方,其中一个令人无法忽视的优点就是它的文档完善程度极好。它甚至有专门的文档生成工具,[Sphinx](http://www.sphinx-doc.org/en/master/): 103 | 104 | > Sphinx is a tool that makes it easy to create intelligent and beautiful documentation, written by Georg Brandl and licensed under the BSD license. 105 | > 106 | > It was originally created for [the Python documentation](https://docs.python.org/), and it has excellent facilities for the documentation of software projects in a range of languages. Of course, this site is also created from reStructuredText sources using Sphinx! 107 | 108 | 最好的 Python 教程,是官方网站上的 [The Python Tutorial](https://docs.python.org/3/tutorial/index.html),读它就够了。我个人完全没兴趣从头到尾写一本 Python 编程教材,不仅因为人家写得真好,而且它就放在那里。 109 | 110 | 虽然你在官方网站上就是很难找到它的中文版,虽然就不告诉你到底在哪里也显得很不厚道,但是,我建议你就只看英文版 —— 因为离开了这个教程之后,还是要面对绝大多数都是英文的现实。 111 | 112 | 为了照顾那些也想读完本书,但因为种种原因想着读中文可以快一些的人,链接还是放在这里: 113 | 114 | > * https://docs.python.org/zh-cn/3/tutorial/index.html (for v.3.7.2) 115 | > * http://www.pythondoc.com/pythontutorial3/ (for v.3.6.3) 116 | 117 | 我曾经专门写过一本书发布在网上,叫《[人人都能用英语](https://github.com/xiaolai/everyone-can-use-english)》。其中的观点就是,大多数人之所以在英语这事上很矬,是因为他们花无数的时间去 _“学”_,但就是 _“不用”_。学以致用,用以促学。可就是不用,无论如何就是不用,那英语学了那么多年能学好吗? 118 | 119 | 自学编程的一个 “副作用” 就是,**你不得不用英语**。而且还是天天用,不停地用。 120 | 121 | 当年我上大学的时候,最初英语当然也不好。不过,因为想读当时还是禁书的《动物庄园》([Animal Farm](https://www.marxists.org/subject/art/literature/children/texts/orwell/animal-farm/index.htm)),就只好看原版(当时好不容易搞到的是本英法对照版)…… 然后英语阅读就基本过关了。 122 | 123 | 这原理大抵上是这样,刚开始,英语就好像一层毛玻璃,隔在你和你很想要了解的内容之间。然而,由于你对那内容的兴趣和需求是如此强烈,乃至于即便隔着毛玻璃你也会挣扎着去看清楚…… 挣扎久了(其实没两天就不一样),你的 “视力” 就进化了,毛玻璃还在那里,但你好像可以穿透它看清一切…… 124 | 125 | 自学编程,也算是一举两得了! 126 | 127 | ## (五) 128 | 129 | 当然,把编程作为 “讲解如何习得自学能力的例子”,实在是太好了的最重要原因在于,自学编程对任何人来说都绝对是: 130 | 131 | > * 现实的(Practical) 132 | > * 可行动的(Actionable) 133 | > * 并且还是真正是可达成的(Achievable) 134 | 135 | 最重要的就是最后这个 “可达成的”。虽然对读者和作者来说,一个做到没那么容易,另一个讲清楚也非常难,但是,既然是所有人都 “可达成的”,总得试试吧?但是,请相信我,这事比减肥容易多了 —— 毕竟,你不是在跟基因作斗争。 136 | 137 | 这只是个起点。 138 | 139 | 尽量只靠阅读学会编程,哪怕仅仅是入门,这个经历和经验都是极为宝贵的。 140 | 141 | 自学是门手艺。只不过它并不像卖油翁的手艺那样很容易被别人看到,也不是很容易拿它出来炫耀 —— 因为别人看不到么!然而,经年累月,就不一样了,那好处管他别人知不知道,自己却清楚得很! 142 | 143 | 你身边总有些人能把别人做不好的事做得极好,你一定很羡慕。可他们为什么能做到那样呢?很简单啊,他们的自学能力强,所以他们能学会大多数自学能力差的人终生学不到的东西。而且他们的自学能力会越来越强,每学会一样新东西,他们就积累了更多自学经验,难以对外言表的经验,再遇到什么新东西,相对没那么吃力。 144 | 145 | 另外,自学者最大的感受就是万物相通。他们经常说的话有这么一句:“…… **到最后,都是一样的呢**。” 146 | 147 | ## (六) 148 | 149 | 最后一个好处,一句话就能说清楚,并且,随着时间的推移,你对此的感触会越来越深: 150 | 151 | > 在这个领域里,自学的人最多…… 152 | 153 | 没有什么比这句话更令人舒心的了:**相信我,你并不孤独**。 154 | -------------------------------------------------------------------------------- /markdown/Part.1.C.must.learn.sth.only.by.reading.md: -------------------------------------------------------------------------------- 1 | 2 | # 只靠阅读习得新技能 3 | 4 | 习得自学能力的终极目标就是: 5 | 6 | > 有能力**只靠阅读**就能习得新技能。 7 | 8 | 退而求其次,是 “尽量只靠阅读就习得新技能” —— 当然,刚开始的时候可能需要有人陪伴,一起学,一起讨论,一起克服困难…… 但就是要摆脱 “没人教,没人带,没人逼,就彻底没戏” 的状态。 9 | 10 | 小时候总是听大人说: 11 | 12 | > 不是什么东西都可以从书本里学到的…… 13 | 14 | 一度,我觉得他们说的有道理。再后来,隐约感觉这话哪儿有毛病,但竟然又感觉无力反驳…… 15 | 16 | 那时,真被他们忽悠到了;后来,也差点被他们彻底忽悠到! 17 | 18 | 幸亏后来我渐渐明白,且越来越相信: 19 | 20 | > 自己生活工作学习上遇到的所有疑问,书本里应该都有答案 —— 起码有所参考。 21 | 22 | “不是什么东西都可以从书本里学到的……” 这话听起来那么有道理,只不过是因为自己读书**不够多**、**不够对**而已。 23 | 24 | 过了 25 岁,我放弃了读小说,虚构类作品,我只选择看电影;而非虚构类作品,我选择尽量只读英文书,虽然那时候买起来很贵也很费劲,但我觉得值 —— 英文世界和中文世界的文化风格略有不同。在英文世界里,你看到的正常作者好像更多地把 “通俗易懂”、“逻辑严谨” 当作最基本的素养;而在中文世界里,好像 “故弄玄虚”、“偷梁换柱” 更常见一些;在英文世界里,遇到读不懂的东西可以很平静地接受自己暂时的愚笨,心平气和地继续努力就好;在中文世界里,遇到装神弄鬼欺世盗名的,弄不好最初根本没认出来,到最后跟 “认贼作父” 一样令人羞辱难当不堪回首。 25 | 26 | 说实话,我真觉得这事跟崇洋媚外没什么关系。我是朝鲜族,去过韩国,真觉得韩国的书更没法看(虽然明显是个人看法)…… 2015 年年底,我的律师告诉我,美国移民就快帮我办下来了,可那时候我开始觉得美国政府也各种乱七八糟,于是决定停止办理。我是个很宅的人,除了餐馆基本上哪儿都不去,陪家人朋友出去所谓旅游的时候,我只不过是换个房间继续宅着…… 可这些都不是重点,重点在于: 27 | 28 | > **知识原本就应该无国界**…… 不是吗?不是吗! 29 | 30 | 再说,这些年我其实还读了不少中国人写的英文书呢,比如,张纯如的书很值得一看;郑念的 Life and Death in Shanghai,真的很好很好。我也读了不少老外写的关于中国的书 —— 这些年我一直推荐费正清的剑桥中国史(The Cambridge History of China),当然有中文版的,不过,能读英文版的话感受很不一样。 31 | 32 | 当然,英文书里同样烂书也很多,烂作者也同样一大堆,胡说八道欺世盗名的一大串…… 但总体上来看,非小说类著作质量的确更高一点。 33 | 34 | 还有,英语在科学研究领域早已成为 “主导语言”(Dominant Language)也是不争的事实。不过,英语成为主导语言的结果,就是英语本身被不断 “强奸”,外来语越来越多,“Long time no see” 被辞典收录就是很好的例子。事实上,英语本身就是个大杂烩…… 35 | 36 | ![Joseph M. Williams’ research visualized (top 10,000 words).](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/Joseph-M-Williams-research-visualized.png?raw=true) 37 | 38 | 读书越多越明白读书少会被忽悠…… 很多人真的会大头捣蒜一般地认同 “不是什么东西都可以从书本里学到的……” 39 | 40 | 另外,很多人在如此教导小朋友的时候,往往是因为 “人心叵测” 啊,“江湖险恶” 啊,所以害怕小朋友吃亏。可事实上,如若说,人间那些勾心斗角的事貌似从书本里学不来的话,其实也不过还是历史书看少了 —— 勾心斗角的套路历史上全都被反复用过了。倒是有本中文书值得吐血推荐,民国时代的作者连阔如先生写的《江湖丛谈》,粗略扫过你就知道了,江湖那点事,也早就有人给你里里外外翻了个遍…… 只不过这书不太容易买到就是了。 41 | 42 | 我也遇到过这样的反驳: 43 | 44 | > 书本能教会你做生意吗?! 45 | 46 | 说实话,去回驳这个反驳还真挺难,因为反驳者是脑容量特别有限才能说出这种话 —— 世界上有那么多商学院都是干嘛的?搞得它们好像不存在一样。首先,它们的存在说明,商业这事是有迹可循的,是可学习的;其次,商业类书籍非常多,是非虚构类书籍中的一大品类;更为重要的是,做生意这事,看谁做 —— 有本事(即,比别人拥有更多技能)的人做生意和没本事的人做生意,用同样的商业技巧,能有一样的效果吗?最后啊,这世界在这方面从来没有变过:一技傍身的人,总是不愁生活…… 47 | 48 | 更为重要的是,这才几年啊,互联网本身已经成了一本大书 —— 关于全世界的一整本大书。仅仅是 10 多年前,大约在 2008 年前后,经过几年发展的 Wikipedia 被众多西方大学教授们群起而攻,指责它错误百出…… 可现在呢?Wikipedia 好像有天生的自我修复基因,它变得越来越值得信赖,越来越好用。 49 | 50 | 七零后八零后长大的过程中,还经常被父母无故呵斥:“怎么就你事这么多!” 或者无奈敷衍:“等你长大了就明白了……” 九零后、零零后呢?他们很少有什么疑问需要向父母提问,直接问搜索引擎,效果就是父母们天天被惊到甚至吓到。最近两年更不一样了,我有朋友在旧金山生活,他的孩子整天跟 Google 说话,有点什么问题,就直接 “Hey Google...” 51 | 52 | 我长大的那个年代,一句 “通过阅读了解世界” 好像还是很抽象甚至很不现实的话,现在呢?现在,除了阅读之外,你还能想出什么更有效的方法吗?反正我想不出。 53 | 54 | 有个很有趣的现象: 55 | 56 | > 人么,只要识字,就忍不住阅读…… 57 | 58 | 只不过,人们阅读的选择很不同而已。有自学能力的人和没有自学能力的人,在这一点上很容易分辨: 59 | 60 | > * 有自学能力的人,选择阅读 “有繁殖能力” 的内容; 61 | > * 没有自学能力的人,阅读只是为了消磨时光…… 62 | 63 | 我把那些能给你带来新视野,能让你改变思考模式,甚至能让你拥有一项新技能的内容称之为 “有繁殖能力的内容”。 64 | 65 | 人都一样,拥有什么样的能力之后,就会忍不住去用,甚至总是连下意识中也要用。 66 | 67 | 那些靠阅读机器算法推送的内容而杀时间的人,恰恰就是因为他们有阅读能力才去不断地读,读啊读,像是那只被打了兴奋剂后来死在滚轮上的小白鼠。如果这些人哪怕有一点点自学能力,那么他们很快就会分辨出自己正在阅读的东西不会刺激自己的产出,只会消磨自己的时间;那么,他们就会主动放弃阅读那些杀时间的内容,把那时间和精力自然而然地用在筛选有繁殖能力的内容,让自己进步,让自己习得更多技能上去了。 68 | 69 | 所以,只要你有一次 “**只靠阅读习得一项新技能**” 的经验,你就变成另外一个人了。你会不由自主、哪怕下意识里都会去运用你新习得的能力…… 从这个角度看,自学很上瘾!能上瘾,却不仅无害,还好处无穷,这样的好事,恐怕也就这一个了罢。 70 | 71 | 我有过只靠阅读学会游泳的经历…… 听起来不像真的吧?更邪门的是,罗永浩同学的蛙泳,是我站在游泳池边,仅靠言语讲解,就让他从入水就扑腾开始三十分钟之内可以开始蛙泳的 —— 虽然当天他第一次蛙泳,一个来回五十米都坚持不下来。 72 | 73 | 仅靠阅读学会新技能不仅是可能的,并且,你随后会发现的真相是: 74 | 75 | > 绝大多数情况下,没人能教你,也不一定有人愿意教你…… 到最后,你想学会或你必须学会什么东西的时候,**你只能靠阅读!** —— 因为其实你谁都靠不上…… 76 | 77 | 我有很多偶像,英国数学家乔治・布尔就是其中一个 —— 因为他就是个基本上只靠阅读自学成才的人。十八、九岁,就自学了微积分 —— 那是将近两百年前,没有 Google,没有 Wikipedia…… 然后他还自己创办了学校,给自己打工…… 从来没有上过大学,后来却被皇家学院聘请为该学院第一个数学教授。然后,人家发明的布尔代数,在百年之后引发了信息革命…… 达芬奇也是这样的人 —— 要说惨,他比所有人都惨…… 因为几乎从一开始就貌似没有谁有资格有能力教他。 78 | 79 | 这些例子都太遥远了。给你讲个我身边的人,我亲自打过很长时间交道的人 —— 此人姓邱,人称邱老板。 80 | 81 | 邱老板所写的区块链交易所引擎,在 Github 上用的是个很霸气的名字,“[貔貅](https://github.com/peatio/peatio)”(英文用了一个生造的词,Peatio)—— 这个 Repo 至 2019 年春节的时候,总计有 2,913 个 Star,有 2,150 个 Fork…… 绝对是全球这个领域中最受关注的开源项目。2017 年 9 月,云币应有关部门要求关闭之前,是全球排名前三的区块链交易所。 82 | 83 | 邱老板当年上学上到几年级呢?初中未读完,所以,跟他聊天随口说成语是很有负担的,因为他真的可能听不懂…… 然而,他的编程、他的英语,全是自学的…… 学到什么地步呢?学到可以创造极有价值的商业项目的地步。他什么学习班都没上过,全靠阅读 —— 基本上只读互联网这本大书。 84 | 85 | 讲真,你没有选择,只靠阅读习得新技能,这是你唯一的出路。 86 | -------------------------------------------------------------------------------- /markdown/Part.1.D.preparation.for.reading.md: -------------------------------------------------------------------------------- 1 | 2 | # 开始阅读前的一些准备 3 | 4 | ## 内容概要 5 | 6 | 关于 Python 编程的第一部分总计 7 章,主要内容概括为: 7 | 8 | > 1. 以布尔值为入口开始理解程序本质 9 | > 1. 了解值的分类和运算方法 10 | > 1. 简要了解流程控制的原理 11 | > 1. 简要了解函数的基本构成 12 | > 1. 相对完整地了解字符串的操作 13 | > 1. 了解各种容器的基础操作 14 | > 1. 简要了解文件的读写操作 15 | 16 | ## 阅读策略 17 | 18 | 首先,不要试图一下子就全部搞懂。这不仅很难,**在最初的时候也完全没必要**。 19 | 20 | 因为这部分的知识结构中,充满了 “过早引用”。请在第一遍粗略完成第 1 部分中的 E1 ~ E7 之后,再去阅读《[如何从容应对 “过早引用”?](Part.1.F.deal-with-forward-references.md)》。 21 | 22 | 其次,这一部分,注定要**反复阅读若干遍**。 23 | 24 | 在开始之前,要明确这一部分的阅读目标。 25 | 26 | 这一部分的目标,不是让你读完之后就可以开始写程序;也不是让你读完之后就对编程或者 Python 编程有了完整的了解,甚至不是让你真的学会什么…… 这一部分的目标,只是让你 “**脱盲**”。 27 | 28 | 不要以为脱盲是很容易的事情。你看,所有人出生的时候,都天然是 “文盲”;人们要上好多年的学,才能够真正 “脱盲” —— 仔细想想吧,小学毕业的时候,所有人就真的彻底脱盲了吗? 29 | 30 | 以中文脱盲为例,学字的同时,还要学习笔划;为了学更多的字,要学拼音,要学如何使用《新华字典》…… 31 | 32 | 学会了一些基础字之后,要学更多的词,而后在练习了那么多造词造句之后,依然会经常用错…… 你看,脱盲,和阅读能力强之间距离很长呢;不仅如此,阅读能力强和写作能力强之间的距离更长…… 33 | 34 | 反复阅读这一部分的结果是: 35 | 36 | > * 你对基本概念有了一定的了解 37 | > * 你开始有能力相对轻松地阅读部分官方文档 38 | > * 你可以读懂一些简单的代码 39 | 40 | 仅此而已。 41 | 42 | ## 心理建设 43 | 44 | 当我们开始学习一项新技能的时候,我们的大脑会不由自主地紧张。可这只不过是多年之间在学校里不断受挫的积累效应 —— 学校里别的地方不一定行,可有个地方特别行:给学生制造全方位、无死角、层层递进的挫败感。 45 | 46 | 可是,你要永远记住两个字: 47 | 48 | > 别怕! 49 | 50 | 用四个字也行: 51 | 52 | > 啥也别怕! 53 | 54 | 六个字也可以: 55 | 56 | > 没什么可怕的! 57 | 58 | 我遇到最多的孱弱之语大抵是这样的: 59 | 60 | > 我一个文科生…… 61 | 62 | 哈哈,从某个层面望过去,其实吧,编程既不是文科也不是理科…… 它更像是 “手工课”。你越学就越清楚这个事实,它就好像是你做木工一样,学会使用一个工具,再学会使用另外一个工具,其实总共就没多少工具。然后,你更多做的是各种拼接的工作,至于能做出什么东西,最后完全靠你的想象力…… 63 | 64 | 十来岁的孩子都可以学会的东西,你怕什么? 65 | 66 | **别怕**,无论说给自己,还是讲给别人,都是一样的,它可能是人生中最重要的鼓励词。 67 | 68 | ## 关于这一部分内容中的代码 69 | 70 | 所有的代码,都可以在选中代码单元格(Code Cell)之后,按快捷键 `⇧ ⏎` 或 `^ ⏎` 执行,查看结果。 71 | 72 | 少量执行结果太长的代码,其输出被设置成了 “Scrolled”,是可以通过触摸板或鼠标滑轮上下滑动的。 73 | 74 | 为了避免大量使用 `print()` 才能看到输出结果,在很多的代码单元格中,开头插入了以下代码: 75 | 76 | ```python 77 | from IPython.core.interactiveshell import InteractiveShell 78 | InteractiveShell.ast_node_interactivity = "all" 79 | ``` 80 | 你可以暂时忽略它们的意义和工作原理。注意:有时,你需要在执行第二次的时候,才能看到全部输出结果。 81 | 82 | 另外,有少量代码示例,为了让读者每次执行的时候看到不同的结果,使用了随机函数,为其中的变量赋值,比如: 83 | 84 | ```python 85 | import random 86 | r = random.randrange(1, 1000) 87 | ``` 88 | 89 | 同样,你可以暂时忽略它们的意义和工作原理;只需要知道因为有它们在,所以每次执行那个单元格中的代码会有不同的结果就可以了。 90 | 91 | 如果你不是直接在网站上浏览这本 “书”、或者不是在阅读印刷版,而是在本地自己搭建 Jupyterlab 环境使用,那么请参阅附录《[Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.md)》。 92 | 93 | > **注意**:尤其需要仔细看看《[Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.md)》的《关于 Jupyter lab themes》这一小节 —— 否则,阅读体验会有很大差别。 94 | 95 | 另外,如果你使用的是 [nteract](https://nteract.io) 桌面版 App 浏览 `.ipynb` 文件,那么有些使用了 `input()` 函数的代码是无法在 nteract 中执行的。 96 | -------------------------------------------------------------------------------- /markdown/Part.2.A.clumsy-and-patience.md: -------------------------------------------------------------------------------- 1 | 2 | # 笨拙与耐心 3 | 4 | 自学的过程,实际上需要拆解为以下四个阶段,虽然它们之间常常有部分重叠: 5 | 6 | > * 学 7 | > * 练 8 | > * 用 9 | > * 造 10 | 11 | 只要识字,就会忍不住阅读;只要感觉上有 “值得学” 的,就会忍不住去学 —— 事实上每个人时时刻刻都在学习,只不过,学习的目标选择与学习的方式以及效率均不相同而已。 12 | 13 | 绝大多数人从未区分过这几个阶段,也从未研究过这几个阶段分别应该如何对待。这就解释了为什么那么多人虽然总是忍不住阅读,总是忍不住学习,但终其一生都没有真正掌握过像样的技能…… 因为他们在第一个阶段就出错,到了第二个阶段就放弃,第三个阶段是直接跳过去的,总是 “对付着用”,至于第四个阶段么,想都没想过…… 14 | 15 | 第一部分的内容,基本用来展示 “学” 的过程。**学,就需要重复**,甚至很多次重复,尤其是在面对充满了 “过早引用” 现象的知识结构的时候。 16 | 17 | 反复学,最锻炼的是 “归纳整理” 的能力。而且,最有意思的,这在大多数情况下还是自动发生的 —— 只要你不断重复,你的大脑会在不自主之间把那些已经掌握的知识点与当前尚未掌握的知识点区分开来,前者处理起来轻松容易,甚至可以跳过;后者需要投入更多的注意力去仔细处理…… 在这个过程中,绝大多数的归纳整理工作自动完成了。最后再加上一点 “刻意的、收尾性的归纳总结整理工作” —— 大功告成。 18 | 19 | 绝大多数人总是希望自己一遍就能学会 —— 于是,注定了失败;而面对注定的失败,却并不知道那与天分、智商全无关系,因为谁都是那样的;于是,默默认定自己没有天分,甚至怀疑自己的智商;于是,默默地离开,希望换个地方验证自己的天分与智商;于是,再次面临注定的失败;于是,一而再再而三地被 “证明” 为天分不够智商不够…… 于是,就变成了那条狗: 20 | 21 | > 在一项心理学实验中,狗是被测试对象。把狗关进栅栏里;然而那栅栏并不算太高,原本狗一使劲就能跳过去。但狗带着电项圈,只要它被发现有要跳过栅栏的企图,它就会被电击…… 几次尝试之后,狗就放弃了跳出栅栏 —— 虽然它其实能跳过去。更为惊人的结果是,随后把这条狗关进很低的栅栏,甚至是它都不用跳直接就可以跨过去的栅栏,它也老老实实地呆在栅栏里。 22 | 23 | 自学是门手艺,编程很大程度上也是一门手艺,掌握它在绝大多数情况下与天分智商全无关系 —— 很多人是在十来岁的时候学会编程的基本技能的。所有的手艺,最基本特征就是: 24 | 25 | > **主要靠时间** 26 | 27 | 这就跟你看人们的车技一样,二十年安全驾龄和刚上路的肯定不一样,但这事跟天分、智商真的没什么关系…… 28 | 29 | 到了第二部分,我们终于进入 “用” 的阶段 —— 嗯?“练” 怎么跳过去了?没有,我们的策略是,**以用带练** —— 在不断应用的过程中带动刻意练习。 30 | 31 | 练和学,是多少有些重合部分的。比如,你可能反复 “学” 了第一部分两三遍,而后就进入了第二部分,开始接触 “用”,在 “用” 的过程中,只要有空,或者只要有需求,你就可能回去 “复习” 一遍第一部分的内容…… 32 | 33 | 无论之前的 “学”,重复了多少遍,一旦开始练,就注定体会到各式各样的笨拙。一会儿漏写了一个引号或者一个括号,一会儿不小心使用了非英文字符的全角符号,要么就是发现自己犯的错误愚蠢且反复发生,比如,语句块起始语句末尾忘了写冒号…… 34 | 35 | 这再正常不过了。 36 | 37 | 每次自学什么新东西的时候,你就把自己想象成 “再次出生的婴儿” —— 其实每次自学,的的确确都是重生。一旦掌握了一项新的技能,你就不再是从前的那个自己,你是另外一个人了。 38 | 39 | 看着婴儿蹒跚学步,的确笨拙,但谁会觉得它不可爱呢? 40 | 41 | 同样的道理,刚开始用一个技能的时候,笨拙其实就是可爱 —— 只不过这时候旁人不再这么觉得而已了,只不过因为你披着一张成年人的皮。然而,你的大脑中正在学习的那一部分,和新生婴儿的大脑没有任何区别。 42 | 43 | 在第一部分的时候,“练” 的必要其实并不大…… 甚至,因为这是 “[过早引用](Part.1.F.deal-with-forward-references.md)” 太多的知识结构,所以,急于练习反倒会有副作用。由于对自己所面对的复杂知识结构(就是过早引用太多的知识结构)认识不够,没有提前的应对策略,所以,他们根据原本的习惯,边学边练,学不明白当然就练不明白,于是,走着走着就挫败感太强,于是,就自然而然地放弃了…… 而且,弄不好,越练越容易出现 “不必要的挫败感”。 44 | 45 | 一切 “主要靠时间” 的活动都一样,都需要在从事之前认真做 “心理建设”。通常情况下,读一本教程,上个学习班,就 “会” 了 —— 几乎肯定是错觉或者幻觉。 46 | 47 | > - 首先要明白,这肯定是个比 “天真的想象” 要长得多的过程。 48 | > - 其次要明白,并且要越来越自然地明白,哪儿哪儿都需要很多重复。读,要读很多遍;练,要练很多遍;做,要做很多遍…… 49 | 50 | 有了这样的心理建设,就相对更容易保持耐心。 51 | 52 | 人们缺乏耐心的常见根源就是 “之前根本就没准备花那么多时间和精力”,所以当然很容易超出 “时间和精力的预算”,当然相对更容易焦虑 —— 就好像没多少本钱的人做生意常常更容易失败一样。 53 | 54 | 这也解释了为什么我在写这本书的过程中,心中锁定的目标群体是大一学生和高一学生(甚至也有初一学生): 55 | 56 | > 他们最有自学的 “本钱”…… 57 | 58 | 离开学校之后,绝大多数人很难再有 “一看一下午”、“一练一整天”、“一玩一整夜” 的本钱。又由于生活的压力越来越大,对 “能够使用” 新技能的 “需求” 越来越紧迫,于是,对任何一次自学的 “时间精力投资” 都缩手缩脚,小里小气…… 59 | 60 | **预算观念**非常重要 —— 这个观念的存在与否,成熟与否,基本上决定一个人未来的盈利能力。 61 | 62 | 大多数人对此不仅不成熟,甚至干脆没有预算观念!—— 这也是为什么绝大多数人不适合创业的最根本原因。 63 | 64 | 不夸张地讲,未来的你只需要恪守一个原则,就很可能会因此超越 99% 的人: 65 | 66 | > 绝对不做预算不够的事情。 67 | 68 | 说来惭愧,我是四十多岁之后,在创业和投资中经历了大量的失败,付了不可想像的学费之后,才深刻理解这条看起来过分简单的原则 —— 亏得本科还是学会计毕业的呢!我的运气在于,在自学这件事上,从来给出的预算都很多…… 69 | 70 | 大约 1984 年,我在远在边疆的延吉市的本地青少年宫参加了一个要交 10 元学费的暑期计算机兴趣班,老师姓金,教的是 BASIC 语言,用的机器是这样的: 71 | 72 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/Acorn-Electron.png?raw=true) 73 | 74 | 它要外接上一个九寸的单色显示器,那时候还没有磁盘,所以,只要一断电,就什么都没有了…… 75 | 76 | 后来上了大学,买书自学 C++,结果在一个地方被卡住了: 77 | 78 | 我写的代码死活编译不过去…… 当时的编译器错误提醒还不像今天这么完善,当时也没有什么 Google 可以随时看看网上是否早就有人遇到过跟我一样的问题…… 当时我身边根本就没有什么别人在玩这些东西,当时的学校里的电脑还很少,需要提前申请所谓的 “上机时间”,后来呢?后来就放弃了。 79 | 80 | 当时是什么东西卡住我了呢?说来都能笑死,或者都能被气死: 81 | 82 | ```c 83 | if (c = 1) { 84 | ... 85 | } 86 | ``` 87 | 88 | 习惯于写 BASIC 的我,“被习惯蒙蔽了双眼”,反复检查那么多遍,完全没看到应该写的是 `c == 1`! 89 | 90 | 一晃就好几年过去,有一天在书店看到一本 C++ 教程,想起来多年前放弃的东西,就把书买回来,在家里的电脑上重新玩了起来…… 然后就想起来问题在哪儿了,然后这事就被我重新捡起来了…… 91 | 92 | 学完了也就学完了,真没地儿用。没地儿用,当然就很少练。 93 | 94 | 又过了好几年,我去新东方教书。2003 年,在写词汇书的过程中,需要统计词频,C++ 倒是用不上,用之前学过它的经验,学了一点 Python,写程序统计词频 ——《TOEFL 核心词汇 21 天突破》到今天还在销售。一个当年 10 块钱学费开始学的技能,就因为这本书,这些年给我 “变现” 了很多钱。 95 | 96 | 我有很多东西都是这样,隔了好多年,才重新捡起来,而后继续前行的。 97 | 98 | 最搞笑的是弹吉他。 99 | 100 | 十五六岁的时候,父亲给我买了一把吉他,理由是: 101 | 102 | > 你连唱歌都跑调,将来咋学英语啊? 103 | 104 | 然后我就开始玩。花 5 块钱上了个培训班,第一天学了一个曲子,第二天就因为打架把吉他砸坏了,害得父亲又去给我买了一把更便宜的…… 105 | 106 | 那个年代学吉他的人,第一首肯定是 “[Romance d'Amour](https://www.youtube.com/results?search_query=Romance+d%27Amour+)”(爱的罗曼史),我当然不例外。那曲子好听啊,好听到弹得不好也好听的地步。 107 | 108 | 然后吧,有一天,在一姑娘面前显摆,竟然没有弹错!弹完之后很得意…… 结果那姑娘一脸迷茫,隔了两三秒钟说,“不还有第二段吗?” —— 我一脸懵蛋,“…… 啊?” 109 | 110 | 可是吧,那第二段我终究没有学…… 其实也练过,但后来因为指骨摔断了,所以再后来的许多年,弹吉他只用拨片。直到…… 直到四十五岁那年。有一天,忽然想起这事,于是找来琴谱试了一下,花了一会的时间顺了下来。 111 | 112 | 所以,我猜我的 “自学能力强” 这件事本身,其实只不过是我投入的预算很多造成的 —— 活到老学到老,在我这里不是空话,所以,相对于别人,我这里只不过是预算太多、太充裕了而已。 113 | 114 | 于是,我学的时候重复得比别人多;练的时候重复得比别人多;到最后用得也相对比别人多很多 —— 这跟是否有天分或者聪明与否全然没有关系。 115 | 116 | 当然,学到的东西多了,就变得更聪明了似的。有高中学历的人通常情况下比只有小学学历的人更聪明 —— 其实就是这个原因而已。而这个现象与天生的智商并不总是正相关。 117 | 118 | 有个现象,不自学的人不知道。 119 | 120 | 真正开始自学且不断自学之后,刚开始总是觉得时间不够用 —— 因为当时的自己和其他人没什么太大区别。 121 | 122 | 随着时间的推移,不仅差异会出现,自我认知差异也开始越来越明显: 123 | 124 | > 别人的时间都白过了,自己的时间都有产出…… 125 | 126 | 到了下一个阶段,在其他人不断焦虑的情况下,自己却开始越来越淡定: 127 | 128 | > 因为早已习惯了投入大量时间换取新技能…… 129 | 130 | 等后来真的开始用这些技能做事,不断地做其他人因为时间白过了或者因为投入的 “预算” 不够而学不会做不到的事情 —— 并且还能充分明白,这并不是自己聪明、有天分的结果;只不过是做了该做的事情,投入了该投入的 “成本” 和 “预算” 而已…… 131 | 132 | 于是,就真的能够理解下面这句话背后的深意: 133 | 134 | > 人生很长,何必惊慌。 135 | 136 | 反正,这事跟天分与智商几乎没有任何关系。 137 | -------------------------------------------------------------------------------- /markdown/Part.2.B.deliberate-practicing.md: -------------------------------------------------------------------------------- 1 | 2 | # 刻意练习 3 | 4 | 在自学的过程中,总是有一些部分需要刻意练习。就好像小时候我们学习汉字,有些人总是把 “武” 这个字上加上一个撇 —— 对他们来说,不去写那个不该有的撇,就是需要刻意练习的。另外一些人倒是不在这个字上出错,但候和侯傻傻地分不清楚(类似的例子不计其数),那么,对他们来说就有了另外需要刻意练习的地方…… 5 | 6 | 手艺这个东西,尤其需要刻意练习。我们说,手艺么,主要是靠时间…… 这里的 “时间”,准确地讲,就是 “刻意练习” 的时间,而不是任何时间。 7 | 8 | 我当过很长时间的英语老师。异常苦于一件事:最有用的道理最没人听。 9 | 10 | 学英语根本就不应该那么难,学了十六年也学不明白 —— 至于嘛!然而,最简单的道理,人们就是听不进去。他们之所以不行,就是因为从未刻意练习。学英语最简单的刻意练习就是朗读。每天朗读一小时,一百天下来就会超越绝大多数人,也会超越自己原本可能永远跨不过去的那个坎 —— 神奇的是,朗读什么无所谓,反正现在有声书那么多…… 更神奇的是,刚开始朗读得好不好听,甚至好不好都无所谓,反正没几天就能体会到大幅进步…… 最神奇的是,这么简单的事,99.99% 的人不做 —— 你身在中国,能理解这个比例真的没有夸张。 11 | 12 | 顺带推荐一下王渊源(John Gordan)的微信公众号: 13 | 14 | > 清晨朗读会 15 | 16 | 到 2019 年 2 月 21 日,王渊源同学的清晨朗读会带着大伙朗读了第 1000 天…… 17 | 18 | 许多年前,资质平庸的我,一直苦恼一件事: 19 | 20 | > * 为什么自己无论干什么都笨手笨脚、差这儿差那儿的…… 21 | > * 为什么与此同时,总是能看到另外一些人,给人感觉 “一出手就是高手” 呢?! 22 | 23 | 这事折磨了我好多年…… 直到后来我当了老师,每年面前流过几万名学生之后,我才 “羞耻” 地反应过来: 24 | 25 | > * 我花在刻意练习上的时间**太少**了; 26 | > * 并且,也没有**刻意思考**哪些地方我应该去刻意练习。 27 | 28 | 而那些看起来 “一出手就是高手” 的人,则恰恰相反,他们不仅花很多时间刻意练习,还总是刻意思考在哪些地方尤其要刻意练习 —— 就是这一点差别造成了那么大的差距。 29 | 30 | 比如,小时候玩琴,因为手骨摔断了,于是就中断了很多刻意练习 —— 后来换成拨片之后,也习惯不好,不做很多基础练习,只是顺着感觉 “胡搞瞎搞”…… 于是,我的琴艺永远是自娱自乐也就刚刚够用的水准,永远上不了下一个台阶。我认识的人之中,许岑同学在这方面就是我这种情况的反向典范。 31 | 32 | 然而,我深刻地意识到,在另外一些地方,若是再 “混” 下去,那这辈子就别想有什么名堂了。所以,我就下决心在必要的地方一定要刻意地练习。印象中我第一个应用这种思考模式与决心的地方就是写书。我花了很长时间去准备第一本书,并且刻意地思考在哪些地方应该刻意地用力 —— 比如,在取书名这件在别人眼里可能并不是很重要的事上,我每天都琢磨,前后换了二十几个名字,最终选定…… 其后每一本出版的书籍,在书名选择上我都 “殚精竭虑” —— 最终的结果是,我的第一本书就是畅销书、长销书 —— 后面的每一本都是。 33 | 34 | 对,所谓的 “混”,解释很简单: 35 | 36 | > **不做刻意练习的人就是在混时间**。 37 | 38 | 需要刻意练习的地方,因人而异。有的人就是不可能让 “武” 字带把刀,不需要刻意练习,但另外一些人不是。有些人就是朗读十分钟的效果跟别人朗读一小时的效果一样地好,但更多的人并不是…… 39 | 40 | 然而,这并不是所谓的 “天分” 差异,这大抵上只相当于正态分布坐标略不相同而已。每个人都一样,都有各自必须刻意练习的地方,都有对别人来说无比容易可偏偏对自己来说就是很难的地方,而且,在这件事上,大家的点虽然各不相同,但总体上需要刻意练习的部分比例都差不多 —— 虽然说不清楚那个比例到底是多少。 41 | 42 | 比如,在学一门新的编程语言时,我常常做这样的刻意练习: 43 | 44 | > **在纸上用笔写程序……** 45 | 46 | 而后,看着纸上的程序,把自己的大脑当作解析器,去判断每一句执行后的结果…… 47 | 48 | 反复确认之后,再在编辑器里输入这个程序 —— 用很慢的速度,确保自己的输入无误…… 49 | 50 | 然后再一运行,十有八九出错 —— 要再反复检查修改很多次才能顺利执行到最后…… 51 | 52 | 为什么要这么做呢?因为我发现自己一旦学另外一个语言的时候,自己的大脑就会经常把这个新的语言与之前学过的其他语言相混淆,这很痛苦。我必须想出一个办法,让之前的也好,之后的也罢,干脆刻在自己的脑子里,不可能相互混淆。 53 | 54 | 我相信不是所有人都有我这样的烦恼和痛苦,虽然他们在我不烦恼不痛苦的地方也可能烦恼痛苦…… 55 | 56 | 然而,于我来讲,这就是**我需要刻意练习**的地方 —— 这也是我**刻意思考**之后才找到的需要刻意练习的地方。 57 | 58 | 你也一样。你需要刻意练习的地方,需要你自己去刻意思考 —— 你和别人不一样,没有人和你一样,就这样。 59 | 60 | 这种事情,过去还真的是所谓 “书本上学不到” 的东西 —— 因为没有哪个作者能做到 “遍历世上所有人的所有特殊情况”…… 不过,互联网这本大书貌似正在突破这种限制,因为有无数的作者在写书,每个人所关注的点也不一样,再加上搜索引擎,所以,你总是可以在互联网这本大书中找到 “竟然与我一样的人”! 61 | 62 | 于是,你可能感受到了,其实吧,所谓 “刻意练习”,其实是 “刻意思考哪里需要刻意练习” 之后最自然不过的事情 —— 所以,**“刻意思考” 才是关键。** 63 | 64 | 应对策略很简单: 65 | 66 | > 准备个专门的地方记录 67 | 68 | 我现在用的最多的就是 iPhone 上的 Notes,一旦遇到什么 “疑似需要刻意练习” 的点,就顺手记录在那里以防不小心忘记或者不小心遗漏。 69 | 70 | 而后有时间的时候就拿出来看看,排列一下优先级,琢磨一下刻意练习的方式,而后找时间刻意练习,如此这般,做到 “尽量不混日子”…… 71 | 72 | 有时候,刻意练习是很容易的,比如,为了让自己记住当前正在学习的编程语言的语法规则,直至 “刻在脑子里一般”,需要做的无非是把编辑器中的 “Auto completion”(自动补全)先关掉三个月 —— 麻烦一点就麻烦一点,坚决不让 Tab 键帮自己哗啦哗啦写上一大片…… 那不叫麻烦,那叫刻意练习。 73 | 74 | 人们常说: 75 | 76 | > 凡事,就怕**琢磨**…… 77 | 78 | 那些高手,无一例外都是善于琢磨的人…… 可是,他们在琢磨什么呢?为什么他们会琢磨那些事呢? 79 | 80 | 你看,所谓的琢磨,其实真的不是很难,只不过,在此之前,你不知道该琢磨什么而已,一旦知道了,剩下的都再自然不过,都会自然而然地发生 —— 事实上,所谓的差别差距,只不过一线间而已。 81 | -------------------------------------------------------------------------------- /markdown/Part.2.C.why-start-from-writing-functions.md: -------------------------------------------------------------------------------- 1 | 2 | # 为什么从函数开始? 3 | 4 | 读完第一部分之后,你多多少少已经 “写” 了一些程序,虽然我们总是说,“这就是让你脱盲”;也就是说,从此之后,你多多少少能够读懂程序,这就已经很好了。 5 | 6 | 可是你无论如何都避免不了已经写了一些,虽然,那所谓的 “写”,不过是 “改” 而已 —— 但毕竟也是一大步。 7 | 8 | 绝大多数编程书籍并不区分学习者的 “读” 与 “写” 这两个实际上应该分离的阶段 —— 虽然现实中这两个阶段总是多多少少重叠一部分。 9 | 10 | 在一个比较自然的过程中,我们总是先学会阅读,而后才开始练习写作;并且,最终,阅读的量一定远远大于写作的量 —— 即,输入远远大于输出。当然,貌似也有例外。据说,香港作家倪匡,他自己后来很少读书,每天咣当咣当地像是打扫陈年旧物倒垃圾一样写作 —— 他几乎是全球最具产量的畅销小说作家,貌似地球另外一端的史蒂芬・金都不如他多。又当然,他的主要输入来自于他早年丰富的人生经历,人家读书,他阅世,所以,实际上并不是输入很少,恰恰相反,是输入太多…… 11 | 12 | 所以,正常情况下,输入多于输出,或者,输入远远多于输出,不仅是自然现象,也是无法改变的规则。 13 | 14 | 于是,我在安排内容的时候,也刻意如此安排。 15 | 16 | 第一部分,主要在于启动读者在编程领域中的 “阅读能力”,到第二部分,才开始逐步启动读者在编程领域中的 “写作能力”。 17 | 18 | 在第二部分启动之前,有时间有耐心的读者可以多做一件事情。 19 | 20 | Python 的代码是开源的,它的代码仓库在 Github 上: 21 | 22 | > https://github.com/python/ 23 | 24 | 在这个代码仓库中,有一个目录下,保存着若干 Python Demo 程序: 25 | 26 | > https://github.com/python/cpython/tree/master/Tools/demo 27 | 28 | 这个目录下的 README 中有说明: 29 | 30 | > This directory contains a collection of demonstration scripts for 31 | > various aspects of Python programming. 32 | > 33 | > * `beer.py` Well-known programming example: Bottles of beer. 34 | > * `eiffel.py` Python advanced magic: A metaclass for Eiffel post/preconditions. 35 | > * `hanoi.py` Well-known programming example: Towers of Hanoi. 36 | > * `life.py` Curses programming: Simple game-of-life. 37 | > * `markov.py` Algorithms: Markov chain simulation. 38 | > * `mcast.py` Network programming: Send and receive UDP multicast packets. 39 | > * `queens.py` Well-known programming example: N-Queens problem. 40 | > * `redemo.py` Regular Expressions: GUI script to test regexes. 41 | > * `rpython.py` Network programming: Small client for remote code execution. 42 | > * `rpythond.py` Network programming: Small server for remote code execution. 43 | > * `sortvisu.py` GUI programming: Visualization of different sort algorithms. 44 | > * `ss1.py` GUI/Application programming: A simple spreadsheet application. 45 | > * `vector.py` Python basics: A vector class with demonstrating special methods. 46 | 47 | 最起码把这其中的以下几个程序都精读一下,看看自己的理解能力: 48 | 49 | > * [beer.py](https://github.com/python/cpython/blob/master/Tools/demo/beer.py) Well-known programming example: Bottles of beer. 50 | > * [eiffel.py](https://github.com/python/cpython/blob/master/Tools/demo/eiffel.py) Python advanced magic: A metaclass for Eiffel post/preconditions. 51 | > * [hanoi.py](https://github.com/python/cpython/blob/master/Tools/demo/hanoi.py) Well-known programming example: Towers of Hanoi. 52 | > * [life.py](https://github.com/python/cpython/blob/master/Tools/demo/life.py) Curses programming: Simple game-of-life. 53 | > * [markov.py](https://github.com/python/cpython/blob/master/Tools/demo/markov.py) Algorithms: Markov chain simulation. 54 | > * [queens.py](https://github.com/python/cpython/blob/master/Tools/demo/queens.py) Well-known programming example: N-Queens problem. 55 | 56 | 就算读不懂也没关系,把读不懂的部分标记下来,接下来就可以 “带着问题学习”…… 57 | 58 | 在未来的时间里,一个好的习惯就是,有空了去读读别人写的代码 —— 理解能力的提高,就靠这个了。你会发现这事跟其他领域的学习没什么区别。你学英语也一样,读多了,自然就读得快了,理解得快了,并且在那过程中自然而然地习得了很多 “句式”,甚至很多 “说理的方法”、“讲故事的策略”…… 然后就自然而然地会写了,从能写一点开始,慢慢到 “很能写”! 59 | 60 | 为了顺利启动第一部分的 “阅读”,特意找了个不一样的入口,“布尔运算”;第二部分,从 “阅读” 过渡到 “写作”,我也同样特意寻找了一个不一样的入口:**从函数开始写起**。 61 | 62 | 从小入手,从来都是自学的好方法。我们没有想着一上来就写程序,而是写 “子程序”、“小程序”、“短程序”。从结构化编程的角度来看,写函数的一个基本要求就是: 63 | 64 | > - 完成一个功能; 65 | > - 只完成一个功能; 66 | > - 没有任何错误地只完成一个功能…… 67 | 68 | 然而,即便是从小入手,任务也没有变得过分简单。其中涉及的话题理解起来并不容易,尽管我们尽量用最简单的例子。涉及的话题有: 69 | 70 | > - 参数的传递 71 | > - 多参数的传递 72 | > - 匿名函数以及函数的别称 73 | > - 递归函数 74 | > - 函数文档 75 | > - 模块 76 | > - 测试驱动编程 77 | > - 可执行程序 78 | 79 | 这些都是你未来写自己的工程时所必须仰仗的基础,马虎不得,疏漏不得。 80 | 81 | 另外,这一部分与第一部分有一个刻意不同的编排,这一部分的每一章之后,**没有写总结** —— 那个总结需要读者自己动手完成。你需要做的不仅仅是每一个章节的总结,整个第二部分读完之后,还要做针对整个 “深入了解函数”(甚至应该包括第一部分已经读过的关于函数的内容)的总结…… 并且,关于函数,这一章并未完全讲完呢,第三部分还有生成器、迭代器、以及装饰器要补充 —— 因为它们多多少少都涉及到下一部分才能深入的内容,所以,在这一部分就暂时没有涉及。 82 | 83 | 你要习惯,归纳、总结、整理的工作,从来都不是一次就能完成的,都需要反复多次之后才能彻底完成。必须习惯这种流程 —— 而不是像那些从未自学过的人一样,对这种东西想当然地全不了解。 84 | 85 | 另外,从现代编程方法论来看,“写作” 部分一上来就从函数入手也的确是 “更正确” 的,因为结构化编程的核心就是拆分任务,把任务拆分到不能再拆分为止 —— 什么时候不能再拆分了呢?就是当一个函数只完成一个功能的时候…… 86 | -------------------------------------------------------------------------------- /markdown/Part.2.D.3-lambda.md: -------------------------------------------------------------------------------- 1 | 2 | # 化名与匿名 3 | 4 | ## 化名 5 | 6 | 在 Python 中,我们可以给一个函数取个**化名**(alias)。 7 | 8 | 以下的代码,我们先是定义了一个名为 `_is_leap` 的函数,而后为它另取了一个化名: 9 | 10 | ```python 11 | from IPython.core.interactiveshell import InteractiveShell 12 | InteractiveShell.ast_node_interactivity = "all" 13 | 14 | def _is_leap(year): 15 | return year % 4 == 0 and (year % 100 != 0 or year % 400 == 0) 16 | 17 | year_leap_bool = _is_leap 18 | year_leap_bool # 19 | year_leap_bool(800) # _is_leap(800) -> True 20 | 21 | id(year_leap_bool) # id() 这个函数可以查询某对象的内存地址 22 | id(_is_leap) # year_leap_bool 和 _is_leap 其实保存在同一个地址中,也就是说,它们是同一个对象。 23 | 24 | type(year_leap_bool) 25 | type(_is_leap) # 它们都是 function 26 | ``` 27 | 28 | 29 | 30 | True 31 | 32 | 4547071648 33 | 34 | 4547071648 35 | 36 | function 37 | 38 | function 39 | 40 | 我们可以看到的是,`id(year_leap_bool)` 和 `id(_is_leap)` 的内存地址是一样的 —— 它们是同一个对象,它们都是函数。所以,当你写 `year_leap_bool = _is_leap` 的时候,相当于给 `_is_leap()` 这个函数取了个化名。 41 | 42 | 在什么样的情况下,要给一个函数取一个化名呢? 43 | 44 | 在任何一个工程里,为函数或者变量取名都是很简单却不容易的事情 —— 因为可能会重名(虽然已经尽量用变量的作用域隔离了),可能会因取名含混而令后来者费解…… 45 | 46 | 所以,仅仅为了少敲几下键盘而给一个函数取个更短的化名,实际上并不是好主意,更不是好习惯。尤其现在的编辑器都支持自动补全和多光标编辑的功能,变量名再长都不构成负担。 47 | 48 | 更多的时候,为函数取一个化名,应该是为了提高代码可读性 —— 对自己或其他人都很重要。 49 | 50 | ## lambda 51 | 52 | 写一个很短的函数可以用 `lambda` 关键字。 53 | 54 | 下面是用 `def` 关键字写函数: 55 | 56 | ```python 57 | def add(x, y): 58 | return x + y 59 | add(3, 5) 60 | ``` 61 | 62 | 8 63 | 64 | 下面是用 `lambda` 关键字写函数: 65 | 66 | ```python 67 | add = lambda x, y: x + y 68 | add(3, 5) 69 | ``` 70 | 71 | 8 72 | 73 | lambda 的语法结构如下: 74 | 75 | > `lambda_expr ::= "lambda" [parameter_list] ":" expression` 76 | 77 | 以上使用的是 BNF 标注。当然,BNF 是你目前并不熟悉的,所以,有疑惑别当回事。 78 | 79 | 反正你已经见到示例了: 80 | 81 | ```python 82 | lambda x, y: x + y 83 | ``` 84 | 85 | 先写上 `lambda` 这个关键字,其后分为两个部分,`:` 之前是参数,之后是表达式;这个表达式的值,就是这个函数的返回值。 86 | 87 | > **注意**:`lambda` 语句中,`:` 之后有且只能有一个表达式。 88 | 89 | 而这个函数呢,没有名字,所以被称为 “匿名函数”。 90 | 91 | `add = lambda x, y: x + y` 92 | 93 | 就相当于是给一个没有名字的函数取了个名字。 94 | 95 | ## lambda 的使用场景 96 | 97 | 那 lambda 这种匿名函数的用处在哪里呢? 98 | 99 | ### 作为某函数的返回值 100 | 101 | 第一个常见的用处是*作为另外一个函数的返回值*。 102 | 103 | 让我们看看 [The Python Tutorial](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions) 中的一个例子。 104 | 105 | ```python 106 | def make_incrementor(n): 107 | return lambda x: x + n 108 | 109 | f = make_incrementor(42) 110 | f(0) 111 | 112 | f(1) 113 | ``` 114 | 115 | 42 116 | 117 | 43 118 | 119 | 这个例子乍看起来很令人迷惑。我们先看看 `f = make_incrementor(42)` 之后,`f` 究竟是什么东西: 120 | 121 | ```python 122 | def make_incrementor(n): 123 | return lambda x: x + n 124 | 125 | f = make_incrementor(42) 126 | f 127 | 128 | id(make_incrementor) 129 | id(f) 130 | ``` 131 | 132 | .(x)> 133 | 134 | 4428443296 135 | 136 | 4428726888 137 | 138 | 首先,要注意,`f` 并不是 `make_incrementor()` 这个函数的化名,如果是给这个函数取个化名,写法应该是: 139 | 140 | ```python 141 | f = make_incrementor 142 | ``` 143 | 144 | 那 `f` 是什么呢?它是 `.(x)>`: 145 | 146 | > * `f = make_incrementor(42)` 是将 `make_incrementor(42)` 的返回值保存到 `f` 这个变量之中; 147 | > * 而 `make_incrementor()` 这个函数接收到 `42` 这个参数之后,返回了一个函数:`lambda x: x + 42`; 148 | > * 于是,`f` 中保存的函数是 `lambda x: x + 42`; 149 | > * 所以,`f(0)` 是向这个匿名函数传递了 `0`,而后,它返回的是 `0 + 42`。 150 | 151 | ### 作为某函数的参数 152 | 153 | 可以拿一些可以接收函数为参数的内建函数做例子。比如,[`map()`](https://docs.python.org/3/library/functions.html#map)。 154 | 155 | > `map`(*function*, *iterable*, *...*) 156 | > 157 | > Return an iterator that applies *function* to every item of *iterable*, yielding the results. If additional *iterable* arguments are passed, *function* must take that many arguments and is applied to the items from all iterables in parallel. With multiple iterables, the iterator stops when the shortest iterable is exhausted. For cases where the function inputs are already arranged into argument tuples, see [`itertools.starmap()`](https://docs.python.org/3/library/itertools.html#itertools.starmap). 158 | 159 | `map()` 这个函数的第一个参数,就是用来接收函数的。随后的参数,是 `iterable` —— 就是可被迭代的对象,比如,各种容器,例如:列表、元组、字典什么的。 160 | 161 | ```python 162 | def double_it(n): 163 | return n * 2 164 | 165 | a_list = [1, 2, 3, 4, 5, 6] 166 | 167 | b_list = list(map(double_it, a_list)) 168 | b_list 169 | 170 | c_list = list(map(lambda x: x * 2, a_list)) 171 | c_list 172 | ``` 173 | 174 | [2, 4, 6, 8, 10, 12] 175 | 176 | [2, 4, 6, 8, 10, 12] 177 | 178 | 显然用 `lambda` 更为简洁。另外,类似完成 `double_it(n)` 这种简单功能的函数,常常有 “用过即弃” 的必要。 179 | 180 | ```python 181 | phonebook = [ 182 | { 183 | 'name': 'john', 184 | 'phone': 9876 185 | }, 186 | { 187 | 'name': 'mike', 188 | 'phone': 5603 189 | }, 190 | { 191 | 'name': 'stan', 192 | 'phone': 6898 193 | }, 194 | { 195 | 'name': 'eric', 196 | 'phone': 7898 197 | } 198 | ] 199 | 200 | phonebook 201 | list(map(lambda x: x['name'], phonebook)) 202 | list(map(lambda x: x['phone'], phonebook)) 203 | ``` 204 | 205 | [{'name': 'john', 'phone': 9876}, 206 | {'name': 'mike', 'phone': 5603}, 207 | {'name': 'stan', 'phone': 6898}, 208 | {'name': 'eric', 'phone': 7898}] 209 | 210 | ['john', 'mike', 'stan', 'eric'] 211 | 212 | [9876, 5603, 6898, 7898] 213 | 214 | 可以给 map() 传递若干个可被迭代对象: 215 | 216 | ```python 217 | a_list = [1, 3, 5] 218 | b_list = [2, 4, 6] 219 | 220 | list(map(lambda x, y: x * y, a_list, b_list)) 221 | ``` 222 | 223 | [2, 12, 30] 224 | 225 | 以上的例子都弄明白了,再去看 [The Python Tutorial](https://docs.python.org/3/tutorial/controlflow.html#lambda-expressions) 中的例子,就不会有任何疑惑了: 226 | 227 | ```python 228 | pairs = [(1, 'one'), (2, 'two'), (3, 'three'), (4, 'four')] 229 | pairs.sort(key=lambda p: p[1]) 230 | pairs 231 | ``` 232 | 233 | [(4, 'four'), (1, 'one'), (3, 'three'), (2, 'two')] 234 | 235 | -------------------------------------------------------------------------------- /markdown/Part.2.E.deliberate-thinking.md: -------------------------------------------------------------------------------- 1 | 2 | # 刻意思考 3 | 4 | 随着时间的推移,你会体会到它的威力: 5 | 6 | > 刻意思考哪儿需要刻意练习 7 | 8 | 只不过是一句话而已,却因知道或不知道,竟然会逐渐形成天壤之别的差异,也是神奇。 9 | 10 | 刻意思考,就是所谓的琢磨。琢磨这事,一旦开始就简单得要死,可无从下手的时候就神秘无比。让我们再看一个 “刻意思考” —— 即,琢磨 —— 的应用领域: 11 | 12 | > **这东西能用在哪儿呢?** 13 | 14 | 很多人学了却没怎么练,有一个很现实的原因 —— 没什么地方用得上。 15 | 16 | 这也怪我们的应试教育,大学前上 12 年学,“学”(更多是被逼的)的绝大多数东西,只有一个能够切实体会到的用处,考试 —— 中考、高考,以及以它们为目标的无数 “模考”…… 于是,反过来,不管学什么东西,除了考试之外,几乎无法想象其他的用处。 17 | 18 | 一旦我们启动了对某项技能的自学之后,在那过程中,最具价值的刻意思考就是,时时刻刻琢磨 “这东西能用在哪儿呢?” 19 | 20 | 比如,当你看到字符串的 Methods 中有一个 `str.zfill()` 的时候,马上就能想到,“嗯!这可以用来批量更名文件……” 21 | 22 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/rename-macos.png?raw=true) 23 | 24 | 虽然现在的 Mac OS 操作系统里已经有相当不错的批量更名工具内建在 Finder 之中(选中多个文件之后,在右键菜单中能看到 `rename` 命令),但这是近期才加进去的功能,几年前却没有 —— 也就是说,几年前的时候,有人可以用 `str.zfill()` 写个简单的程序完成自己的工作,而另外一些人仅因为操作系统没有提供类似的功能就要么手工做,要么干脆忍着忘了算了…… 25 | 26 | 但更多的时候,需要你花时间去琢磨,才能找到用处。 27 | 28 | 找到用处,有时候还真挺难的 —— 因为人都一样,容易被自己的眼界所限,放眼望过去,没有用处,自然也就不用了,甚至不用学了,更不用提那就肯定是感觉不用练了…… 29 | 30 | 所以,仔细想想罢 —— 那些在学校里帮老师干活的小朋友们,更多情况下还真不是很多人以为的 “拍马屁”(不排除肯定有哈),只不过是在 “主动找活干”…… 31 | 32 | **找活干**,是应用所学的最有效方式,有活干,所以就有问题需要解决,所以就有机会反复攻关,在这个过程中,**以用带练**…… 33 | 34 | 所以,很多人在很多事上都想反了。 35 | 36 | 人们常常取笑那些呼哧呼哧干活的人,笑着说,“能者多劳”,觉得他们有点傻。 37 | 38 | 这话真的没错。但这么说更准:**劳者多能** —— 你看,都想反了吧? 39 | 40 | 到最后,一切自学能力差的人,外部的表现都差不多,都起码包括这么一条:眼里没活。他们也不喜欢干活,甚至也没想过,玩乐也是干活(每次逢年过节玩得累死那种)—— 从消耗或者成本的角度来看根本没啥区别 —— 只不过那些通常都是没有产出的活而已。 41 | 42 | 在最初想不出有什么用处的时候,还可以退而求其次,看看 “别人想出什么用处没有?” —— 比如,我去 Google `best applications of python skill`,在第一个页面我就发现了这么篇文章:“[What exactly can you do with Python? ](https://medium.freecodecamp.org/what-can-you-do-with-python-the-3-main-applications-518db9a68a78)”,翻了一会儿觉得颇有意思…… 43 | 44 | 再高阶一点的刻意思考(琢磨),无非是在 “这东西能用在哪儿呢?” 这句话里加上一个字而已: 45 | 46 | > 这东西**还**能用在哪儿呢? 47 | 48 | 我觉得这个问题对思维训练的帮助非常深刻 —— 别看只是多了一个字而已。 49 | 50 | 当我读到在编程的过程中有很多的 “约定” 的时候,就琢磨着: 51 | 52 | > * 哦,原来约定如此重要…… 53 | > * 哦,原来竟然有那么多人不重视约定…… 54 | > * 哦,原来就应该直接过滤掉那些不遵守约定的人…… 55 | > —— 那这个原理(东西)还能用在哪儿呢? 56 | > —— 哦,在生活中也一样,遇到不遵守约定的人或事,直接过滤,不要浪费自己的生命…… 57 | 58 | 学编程真的很有意思,因为这个领域是世界上最聪明的人群之一开辟出来并不断共同努力着发展的,所以,在这个世界里有很多思考方式,琢磨方式,甚至可以干脆称为 “做事哲学” 的东西,可以普遍应用在其它领域,甚至其它任何领域。 59 | 60 | 比如,在开发方法论中,有一个叫做 [MoSCoW Method](https://en.wikipedia.org/wiki/MoSCoW_method) 的东西,1994 年由 Clegg Dai 在《Case Method Fast-Track: A RAD Approach》一书中提出的 —— 两个 `o` 字母放在那里,是为了能够把这个缩写读出来,发音跟莫斯科一样。 61 | 62 | 简单说,就是,凡事都可以分为: 63 | 64 | > * Must have 65 | > * Should have 66 | > * Could have 67 | > * Won't have 68 | 69 | 于是,在开发的时候,把所谓的需求打上这 4 个标签中的某一个,以此分类,就很容易剔除掉那些实际上做了还不如不做的功能…… 70 | 71 | 琢磨一下罢,这个东西还可以用在什么地方? 72 | 73 | 显然,除了编程之外,其他应用领域挺多的,这个原则相当地有启发性…… 74 | 75 | 我写书就是这样的。在准备的过程中 —— 这个过程比绝大多数人想象得长很多 —— 我会罗列所有我能想到的相关话题…… 等我觉得已经再也没有什么可补充的时候,再为这些话题写上几句话构成大纲…… 这时候就会发现很多话题其实应该是同一个话题。如此这般,一次扩张,一次收缩之后,就会进行下一步,应用 MoSCoW 原则,给这些话题打上标签 —— 在这过程中,总是发现很多之前感觉必要的话题,其实可以打上 `Won't have` 的标签,于是,把它们剔除,然后从 `Must have` 开始写起,直到 `Should have`,至于 `Could have` 看时间是否允许,看情况,比如,看有没有最后期限限制…… 76 | 77 | 在写书这事上,我总是给人感觉很快,事实上也是,因为有方法论 —— 但显然,那方法论不是从某一本 “如何写书” 的书里获得的,而是从另外一个看起来完全不相关的领域里习得后琢磨到的…… 78 | 79 | 所谓的 “活学活用”,所谓的 “触类旁通”,也不过如此。 80 | -------------------------------------------------------------------------------- /markdown/Part.3.A.conquering-difficulties.md: -------------------------------------------------------------------------------- 1 | 2 | # 战胜难点 3 | 4 | 无论学什么,都有难点。所谓的 “学习曲线陡峭”,无非就是难点靠前、难点很多、难点貌似很难而已。 5 | 6 | 然而,相信我,所有的难点,事实上都可以被拆解成更小的单元,而后在逐一突破的时候,就没那么难了。逐一突破全部完成之后,再拼起来重新审视的时候就会发现那所谓的难常常只不过是错觉、幻觉而已 —— 我把它称为**困难幻觉**。 7 | 8 | 把一切都当作手艺看的好处之一就是心态平和,因为你知道那不靠天分和智商,它靠的是另外几件事:不混时间,刻意思考,以及刻意练习 —— 其实吧,老祖宗早就有总结: 9 | 10 | > 天下无难事,只怕**有心人**…… 11 | 12 | 大家都是人,咋可能没 “心” 呢? 13 | 14 | 想成为有心人,其实无非就是学会拆解之后逐一突破,就这么简单。 15 | 16 | 第三部分所用的例子依然非常简单 —— 这当然是作者的刻意;但是,所涉及的话题都是被认为 “很难很难”、“很不容易理解”、“初学者就没必要学那些了” 之类的话题: 17 | 18 | > * 类,以及面向对象编程(Class,OOP) 19 | > * 迭代器、生成器、装饰器(Iterators、Generators、Decorators) 20 | > * 正则表达式(Regular Expressions) 21 | > * 巴科斯-诺尔范式(Backus Normal Form) 22 | 23 | 尤其是最后一个,巴科斯-诺尔范式,几乎所有的编程入门书籍都不会提到…… 24 | 25 | 然而,这些内容,在我设计《自学是门手艺》内容的过程中,是被当作 `Must have`,而不是 `Should have`,当然更不是 `Could have` 或者 `Won't have` 的。 26 | 27 | 它们属于 `Must have` 的原因也很简单: 28 | 29 | > 无论学什么都一样,难的部分不学会,就等于整个没学。 30 | 31 | —— 仅因为不够全面。 32 | 33 | 有什么必要干前功尽弃的事情呢?要么干脆别学算了,何必把自己搞成一个半吊子?—— 可惜,这偏偏是绝大多数人的习惯,学什么都一样,容易的部分糊弄糊弄,困难的部分直接回避…… 其实,所有焦虑,都是这样在许多年前被埋下,在许多年后生根发芽、茂盛发达的 —— 你想想看是不是如此? 34 | 35 | 虽然别人认为难,你刚开始也会有这样的错觉,但只要你开始施展 “读不懂也要读完,读完之后再读很多遍” 的手段,并且还 “不断自己动手归纳总结整理”,你就会 “发现”,其实没什么大不了的,甚至你会有错觉: 36 | 37 | > “突然” 之间一切都明了了! 38 | 39 | 那个 “突然”,其实就是阿基米德的 [Eureka](https://en.wikipedia.org/wiki/Eureka_effect),那个他从澡堂里冲出来大喊大叫的词汇。 40 | 41 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/archimedes-eureka.png?raw=true) 42 | 43 | 其实吧,泡澡和冥想,还真是最容易产生 Eureka 状态的两种活动。原理在于,泡澡和打坐的时候,大脑都极其放松,乃至于原本相互之间并无联系的脑神经突触之间突然产生相互关联;而那结果就是日常生活中所描述的 “融会贯通”,于是,突然之间,Eureka! 44 | 45 | 自学者总是感觉幸福度很高,就是这个原因。日常中因为自学,所以总是遇到更多的困难。又因为这些东西不过是手艺,没什么可能终其一生也解决不了,恰恰相反,都是假以时日必然解决的 “困难”…… 于是,自学者恰恰因为遇到的 “困难” 多,所以才有更多遇到 “Eureka” 的可能性,那种幸福,还真的难以表述,即便表述清楚了,身边的人也难以理解,因为自学者就是很少很少。 46 | 47 | 对很多人来说,阅读的难点在于起初的时候它总是显得异常枯燥。 48 | 49 | 刚识字、刚上学的时候,由于理解能力有限,又由于年龄的关系于是耐心有限,所以,那时需要老师耐心陪伴、悉心引导。这就好像小朋友刚出生的时候,没有牙齿,所以只能喝奶差不多…… 然而,到了一定程度之后一定要断奶,是不是?可绝大多数人的实际情况却是,小学的时候爱上了 “奶嘴”(有人带着阅读),而后一生没有奶嘴就吃不下任何东西。 50 | 51 | 他们必须去 “上课”,需要有人给他们讲书。不仅如此,讲得 “不生动”、“不幽默” 还不行;就算那职业提供奶嘴的人(这是非常令人遗憾的真相:很多的时候,所谓的 “老师” 本质上只不过就是奶妈而已)帅气漂亮、生动幽默、尽职尽力…… 最终还是一样的结果 —— 绝大多数人依然没有完整掌握所有应该掌握的细节。 52 | 53 | 开始 “自学” 的活动,本质上来看,和**断奶**其实是一回事。 54 | 55 | > * 知识就是知识,它没有任何义务去具备幽默生动的属性; 56 | > * 手艺就是手艺,它没有任何义务去具备有趣欢乐的属性。 57 | 58 | 幽默与生动,是要自己去扮演的角色;有趣与欢乐,是要自己去挖掘的幸福 —— 它们从来都并不自动包含在知识和手艺之中。只有当它们被 “有心人” 掌握、被 “有心人” 应用、甚至被 “有心人” 拿去创造的时候,也只有 “有心人” 才能体会到那幽默与生动、那有趣与欢乐。 59 | 60 | 所以,有自学能力的人,不怕枯燥 —— 因为那本来就理应是枯燥的。这就好像人生本无意义,有意义的人生都是自己活出来的一样,有意义的知识都是自己用出来的 —— 对不用它的人,用不上它的人来说,只能也只剩下无法容忍的枯燥。 61 | 62 | 能够**耐心**读完那么多在别人看来 “极度枯燥” 的资料,是自学者的擅长。可那在别人看来 “无以伦比” 的耐心,究竟是哪儿来的呢?如何造就的呢?没断奶的人想象不出来。其实也很简单,首先,平静地接受了它枯燥的本质;其次,就是经过多次实践已然明白,无论多枯燥,总能读完;无论多难,多读几遍总能读懂…… 于是,到最后,**只不过是习惯了而已。** 63 | 64 | 第三部分关于编程的内容过后,还有若干关于自学的内容。 65 | 66 | 在反复阅读编程部分突破难点的过程之中、过程之后,你会对那些关于自学的内容有更深更生动的认识。很多道理过去你都知道是对的,只不过因为没有遇到过生动的例子 —— 主要是没遇到过能让自己感到生动的例子 —— 于是你就一直没有重视起来,于是,就还是那句话,那一点点的差异,造成了后来那么大的差距。 67 | 68 | 然而,既然知道了真相的你,以后就再也没办法蒙蔽自己了 —— 这就是收获,这就是进步。 69 | -------------------------------------------------------------------------------- /markdown/Part.3.B.1.classes-1.md: -------------------------------------------------------------------------------- 1 | 2 | # 类 —— 面向对象编程 3 | 4 | ## 面向对象编程 5 | 6 | 注意:当前这一小节所论述的内容,不是专属于哪个编程语言(比如 Python、JavaScript 或者 Golang)。 7 | 8 | 面向对象编程([Object Oriented Programming, OOP](https://en.wikipedia.org/wiki/Object-oriented_programming))是一种编程的范式(Paradigm),或者说,是一种方法论(Methodology)—— 可以说这是个很伟大的方法论,在我看来,现代软件工程能做那么复杂的宏伟项目,基本上都得益于这个方法论的普及。 9 | 10 | ## 争议 11 | 12 | 现在,OOP 的支持者与反对者在数量上肯定不是一个等级,绝大多数人支持 OOP 这种编程范式。 13 | 14 | 但是,从另外一个角度,反对 OOP 的人群中,牛人比例更高 —— 这也是个看起来颇为吊诡的事实。 15 | 16 | 比如,Erlang 的发明者,[Joe Armstrong](https://en.wikipedia.org/wiki/Joe_Armstrong_(programmer)) 就很讨厌 OOP,觉得它效率低下。他用的类比也确实令人忍俊不禁,说得也挺准的: 17 | 18 | > 支持 OOP 的语言的问题在于,它们总是随身携带着一堆并不明确的环境 —— 你明明只不过想要个香蕉,可你所获得的是一个大猩猩手里拿着香蕉…… 以及那大猩猩身后的整个丛林!
—— [Coders at Work](http://www.codersatwork.com) 19 | 20 | 创作 UTF-8 和 Golang 的程序员 [Rob Pike](https://en.wikipedia.org/wiki/Rob_Pike),更看不上 OOP,在 2004 年的一个讨论帖里直接把 OOP 比作 “[Roman numerals of computing](https://groups.google.com/forum/#!topic/comp.os.plan9/VUUznNK2t4Q%5B151-175%5D)” —— 讽刺它就是很土很低效的东西。八年后又[挖坟把一个 Java 教授写的 OOP 文章嘲弄了一番](https://plus.google.com/+RobPikeTheHuman/posts/hoJdanihKwb):“也不知道是什么脑子,认为写 6 个新的 Class 比直接用 1 行表格搜索更好?” 21 | 22 | [Paul Graham](https://en.wikipedia.org/wiki/Paul_Graham_(programmer) —— 就是那个著名的 Y-Combinator 的创始人 —— 也一样对 OOP 不以为然,在 [Why Arc isn't Especially Object-Oriented](http://www.paulgraham.com/noop.html) 中,说他认为 OOP 之所以流行,就是因为平庸程序员(Mediocre programers)太多,大公司用这种编程范式去阻止那帮家伙,让他们捅不出太大的娄子…… 23 | 24 | 然而,争议归争议,应用归应用 —— 就好像英语的弊端不见得比其他语言少,可就是最流行,那怎么办呢?用呗 —— 虽然该抱怨的时候也得抱怨抱怨。 25 | 26 | 从另外一个角度望过去,大牛们如此评价 OOP 也是很容易理解的 —— 因为他们太聪明,又因为他们太懒得花时间去理解或容忍笨蛋…… 我们不一样,最不一样的地方在于,我们不仅更多容忍他人,而且更能够容忍自己的愚笨,所以,视角就不同了,仅此而已。 27 | 28 | 并且,上面两位大牛写的编程语言,现在也挺流行,Joe Armstrong 的 Erlang 和 Rob Pike 的 Golang,弄不好早晚你也得去学学,去用用…… 29 | 30 | ## 基本术语 31 | 32 | 面向对象编程(OOP),是使用**对象**(Objects)作为核心的编程方式。进而就可以把对象(Objects)的数据和运算过程**封装**(Encapsulate)在内部,而外部仅能根据事先设计好的**界面**(Interface)与之沟通。 33 | 34 | 比如,你可以把灯泡想象成一个对象,使用*灯泡*的人,只需要与*开关*这个界面(Interface)打交道,而不必关心灯泡内部的设计和原理 —— 说实话,这是个很伟大的设计思想。 35 | 36 | 生活中,我们会遇到无数有意无意应用了这种设计思想的产品 —— 并不仅限于编程领域。你去买个车回来,它也一样是各种封装之后的对象。当你转动方向盘(操作界面)的时候,你并不需要关心汽车设计者是如何做到把那个方向盘和车轮车轴联系在一起并如你所愿去转向的;你只需要知道的是,逆时针转动方向盘是左转,而顺时针转动方向盘是右转 —— 这就可以了! 37 | 38 | 在程序设计过程中,我们常常需要对标现实世界创造对象。这时候我们用的最直接手段就是**抽象**(Abstract)。抽象这个手段,在现实中漫画家们最常用。为什么你看到下面的图片觉得它们俩看起来像是人?尤其是在你明明知道那肯定不是人的情况下,却已然接受那是两个漫画小人的形象? 39 | 40 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/a-cartoon.png?raw=true) 41 | 42 | 这种描绘方式,就是抽象,很多 “没必要” 的细节都被去掉了(或者反过来说,没有被采用),留下的两个特征,一个是头,一个是双眼 —— 连那双 “眼睛” 都抽象到只剩下一个黑点了…… 43 | 44 | 这种被保留下来的 “必要的特征”,叫做对象的**属性**(Attributes),进而,这些抽象的对象,既然是 “人” 的映射,它们实际上也能做一些抽象过后被保留下来的 “必要的行为”,比如,说话,哭笑,这些叫做对象的**方法**(Methods)。 45 | 46 | 从用编程语言创造对象的角度去看,所谓的界面,就由这两样东西构成: 47 | 48 | > * *属性* —— 用自然语言描述,通常是名词(Nouns) 49 | > * *方法* —— 用自然语言描述,通常是动词(Verbs) 50 | 51 | 从另外一个方面来看,在设计复杂对象的时候,抽象到极致是一种必要。 52 | 53 | 我们为生物分类,就是一层又一层地抽象的过程。当我们使用 “生物” 这个词的时候,它并不是某一个特定的我们能够指称的东西…… 然后我们开始给它分类…… 54 | 55 | [![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/Tree-of-Life.gif?raw=true)](https://crucialconsiderations.org/wp-content/uploads/2016/08/Tree-of-Life.jpg) 56 | 57 | 所以,当我们在程序里创建对象的时候,做法常常是 58 | 59 | > * 先创建最抽象的**类**(Class) 60 | > * 然后再创建**子类**(Subclass)…… 61 | 62 | 它们之间是从属关系是: 63 | 64 | > Class ⊃ Subclass 65 | 66 | 在 OOP 中,这叫**继承**(Inheritance)关系。比如,狗这个*对象*,就可以是从哺乳动物这个对象*继承*过来的。如果哺乳动物有 “头” 这个*属性*(Attributes),那么在狗这个对象中就没必要再重新定义这个属性了,因为既然狗是从哺乳动物继承过来的,那么它就拥有哺乳动物的所有属性…… 67 | 68 | 每当我们创建好一个类之后,我们就可以根据它创建它的许多个**实例**(Instances)。比如,创建好了 “狗” 这个类之后,我们就可以根据这个类创建很多条狗…… 这好多条狗,就是狗这个类的*实例*。 69 | 70 | 现在能把这些术语全部关联起来了吗? 71 | 72 | > * 对象,封装,抽象 73 | > * 界面,属性,方法 74 | > * 继承,类,子类,实例 75 | 76 | 这些就是关于 “面向对象编程” 方法论的最基本的术语 —— 无论在哪种编程语言里,你都会频繁地遇到它们。 77 | 78 | **对象**、**类**,这两个词,给人的感觉是经常被通用 —— 习惯了还好,但对有些初学者来说,就感觉那是生命不能承受之重。—— 这次不是英文翻译中文时出现的问题,在英文世界里,这些词的互通使用和滥用也使相当一部分人(我怀疑是大部分人)最终掌握不了 OOP 这个方法论。 79 | 80 | 细微的差异在于 “视角” 的不同。 81 | 82 | 之前提到函数的时候,我用的说辞是, 83 | 84 | > - 你写了一个函数,而后你要为这个产品的使用者写说明书…… 85 | > - —— 当然,产品使用者之中也包括未来的你…… 86 | 87 | 类(Class)这个东西也一样,它也有创作者和使用者。 88 | 89 | 你可以这样分步理解: 90 | 91 | > * 你创造了一个类(Class),这时候你是创作者,从你眼里望过去,那就是个类(Class); 92 | > * 而后你根据这个类的定义,创建了很多实例(Instances); 93 | > * 接下来一旦你开始使用这些实例的时候,你就成了使用者,从使用者角度望过去,手里正在操作的,就是各种对象(Objects)…… 94 | 95 | 最后,补充一下,不要误以为所有的 Classes 都是对事物(即,名词)的映射 —— 虽然大多数情况下确实如此。 96 | 97 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/code-review.png?raw=true) 98 | 99 | 对基本概念有了一定的了解之后,再去看 Python 语言是如何实现的,就感觉没那么难了。 100 | -------------------------------------------------------------------------------- /markdown/Part.3.G.the-golden-age-and-google.md: -------------------------------------------------------------------------------- 1 | 2 | # 这是自学者的黄金时代 3 | 4 | 历史上,自学者从未像今天这样幸福。 5 | 6 | 以前不是这样的。比如,几乎每个中国人从小就听说过无数次那种 “为了拜师学艺一跪就几天甚至几个月也不一定被收下” 的故事。 7 | 8 | 在古代,拜师学艺的确是很难的事情。首先,真正的好老师确实难寻;其次,高手也没空当老师;再次,就算是肯收徒授艺的老师也总是时间精力极其有限…… 更为重要的是,那时候想自学也真不行 —— 根本就没有什么称得上是文献的东西可供阅读或检索,很多重要信息甚至干脆只存在于某些人的脑中,就算它们被落实成了文献,也相当有限,且散落深藏在各处 —— 就算凑齐了,也没有 [Google](https://www.google.com/ncr)! 9 | 10 | 对,最关键的是那时候没有 Google…… 11 | 12 | 今天的互联网,已经不再是二十几年前刚出现的那样 “激进而简陋” 的东西了。经过多年的发展,互联网上的内容已经构成了真正意义上的 “全球唯一通用图书馆” —— 而针对它可用的检索工具中最好的,当然是 Google。 13 | 14 | 于是,今天,自学者在真正的意义上身处于一个黄金时代 —— **没有什么是不能自学的**。注意措辞,在这句话前面甚至根本不用加上 “几乎” 这样的限定以示准确 —— 你想学什么,就能学什么,而不是 “只有先拜师才能开始学艺”。 15 | 16 | 今天的你,想学什么就去问 Google;在学习中遇到什么问题,就直接问 Google —— 直接问它,通常总是比向某个人提问有效率得多。Google 就是这样,越用越离不开它…… 17 | 18 | 其实很多人并不真的懂如何用好 Google 的,可是连这个它也能解决,因为你可以直接问它: 19 | 20 | > [How to use google effectively](https://www.google.com/search?q=How+to+use+google+effectively) 21 | 22 | 经过多年的发展,Google 的使用体验越来越好,2019 年的今天,你搜索以上语句返回的页面里,Google 甚至在众多搜索结果中选了一条它 “认为” 是 “最佳” 的搜索结果: 23 | 24 | ![google-how-effectively](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/google-how-effectively.png?raw=true) 25 | 26 | [lifehack.com 上的这篇文章](https://www.lifehack.org/articles/technology/20-tips-use-google-search-efficiently.html)也的的确确值得细读 —— 读过且真正理解之后,不夸张地讲,你的 “搜索技能” 已经足够灭掉整个人类当前活跃群体中的 99% 了…… 这个说法真的完全没有夸张,绝大多数人就是不会在搜索的过程中使用那些符号的,比如 `-` `*` `~` `@` `#` `:` `"` `..` —— 还有很多其它技巧…… 话说,你在 Google 上用过 `Time *place*` 吗? 27 | 28 | 已经掌握了正则表达式以及 glob 的你,学习一下如何使用这种符号,实在是太小菜一碟了 —— 然而,这么简单的东西所能带来的未来收益是非常惊人的,不信走着瞧。 29 | 30 | 可实际上,还是得应用我们之前说过的原则: 31 | 32 | > 首选查询,肯定是官方文档。 33 | 34 | 这么做的重要理由之一,是为了让你少受 “二手知识” 的蒙蔽和误导。这里有一个绝佳的例子让你理解二手知识的局限性:[我写过的一本 “书”,发布在网上](https://github.com/xiaolai/ji) —— 这本 “书” 的另外一个 “神” 之处,在于它能让你 “顿悟” 阅读的力量,不管你是男生还是女生…… 若是这个链接错过了,你竟然会错过整个生活! 35 | 36 | Google Search 的官方文档在这里: 37 | 38 | > https://support.google.com/websearch 39 | 40 | Google 还有更为强大的工具给你使用,叫做 Google Custom Search,官方文档在这里: 41 | 42 | > https://support.google.com/customsearch/ 43 | 44 | 对编程工作来说,Google 当然格外地更为重要 —— 互联网上积累的最多最专业的信息,当然是计算机相关信息。所以,当你遇到什么错误提示的时候,不仅要问 Google,还要优先问问 [Stackoverflow](https://stackoverflow.com) —— 连 Google 自己都这么干。在 [colab.research.google.com](https://colab.research.google.com)(Google 为它的 TensorFlow 服务搭建的 Jupyterlab 环境)上,如果你运行什么代码出错了的话,那么,出错信息下面会出现一个按钮,上面写着:`SEARCH STACK OVERFLOW`,点击它就直接给你 [Stackoverflow](https://stackoverflow.com) 上的搜索结果…… 真够意思! 45 | 46 | ![google-stackoverflow](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/google-stackoverflow.png?raw=true) 47 | 48 | [Google](https://google.com)、[Stackoverflow](https://stackoverflow.com)、[Wikipedia](https://en.wikipedia.org)、[Youtube](https://youtube.com),这些都是你经常要去搜索的好地方。 49 | 50 | 二十年前,Google 刚出现的时候,谁能想象它今天这个样子呢?以下是 1998 年 11 月 11 日 http://google.com 这个网址的截图: 51 | 52 | ![google-homepage-1998](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/google-homepage-1998.png?raw=true) 53 | 54 | 当时,网站还没有正式上线,第一个链接是一个原型设计,用一个二级域名发布在斯坦福的网站上:http://google.stanford.edu/: 55 | 56 | ![google-prototype-1998](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/google-prototype-1998.png?raw=true) 57 | 58 | 那个时候,Google 还要向外人强调一下,他们已经有 2500 万页面可供检索! 59 | 60 | 事实上,到了 2008 年,Google 公告称,可供检索页面已经超过一万亿(One Trillion),到了 2016 年年底,这个数字已经超过 130 万亿…… 61 | 62 | 换个角度看,这个数字同时也是互联网上信息的积累 —— 世界上再没有比互联网更大更全的 “书” 了。并且,由于 Google 的存在,互联网这本大书,是可检索的! 63 | 64 | 于是,**有事先问 Google** 就成了自学者的必备修养。 65 | 66 | > 能 Google 出答案的问题,就不需要去麻烦别人。 67 | 68 | 这也是一个自学者的基本素养。 69 | 70 | 偶尔,也确实会遇到 Google 了很久,就是没有找到答案的情况…… 这样的时候,你可能需要想办法 “问人” 了。然而,最靠谱的通常并不见得是 “身边的人”,而是互联网上各种垂直社区里的其他用户…… 71 | 72 | 向人问,也是有学问的 —— 很多人张口就问,结果呢?结果没人理。为什么呢? 73 | 74 | 作为一个有素养的自学者,有一篇文章必须精读: 75 | 76 | > [How To Ask Questions The Smart Way](https://github.com/selfteaching/How-To-Ask-Questions-The-Smart-Way) 77 | 78 | 这是大神 Eric S. Raymond 和 Rick Moen 于 2001 年在网上发布的文章,被人们奉为经典;迄今为止经历了很多次的修订,最后一次是在 2014 年,`Revision 3.10` —— 前后被翻译成了许多种语言。 79 | 80 | **不认真使用 Google,你就错过了整个人类历史上自学者最黄金的时代。** 81 | -------------------------------------------------------------------------------- /markdown/Part.3.H.prevent-focus-drifting.md: -------------------------------------------------------------------------------- 1 | 2 | # 避免注意力漂移 3 | 4 | **注意力漂移**,是我杜撰的一个词,用来作为 “注意力集中” 的反义词 —— 因为更多的时候,我们并不是 “注意力不集中”,而是…… 而是更令人恼火的一个现象: 5 | 6 | > “注意力所集中的焦点总是不断被自己偷偷换掉……” 7 | 8 | 比如,你本来只不过就想着去 Google 一个编程错误信息的解读,结果不知道怎么就 “注意到” 了另外一个东西,比如,“某编辑器的皮肤”,然后你就 “顺手” 把它下载下来,然后 “很自然地顺手把它装上”,而后又看了看,觉得有点必要于是 “顺手做了点定制”…… 然后欣赏了一会儿,并自我得意一番之后 “突然发现” 自己还没有解决两小时之前要解决的问题! 9 | 10 | 说这种现象 “令人恼火”,是因为那注意力所集中的焦点,是被**自己**偷偷换掉的! 11 | 12 | 好奇心越重的人,越是容易被注意力漂移所拖累。 13 | 14 | 好奇心是好东西,而且是必须认真呵护的东西 —— 几乎最重要、最强劲的自学动力,都混合着好奇心出现并持续。 15 | 16 | 在我成长的那个年代里,很多孩子本来是可以成为自学专家的,结果,99.99% 都被父母给毁了 —— 而且还是不经意地毁的。那些父母毁掉自己孩子的方法简单直接又粗暴、且毫不犹豫。 17 | 18 | 刚开始图好玩,小孩子问啥都回答…… 当然,最初的时候,小孩子问的问题也很容易回答;就算不容易,也很容易糊弄过去。没多久,父母就开始应付不过来了,一方面自己也没那么多耐心了,另外一方面是更为严重的问题 —— 自己的脑力不够。再加上那时候也没有 Google,所以,父母的反应惊人地一致:“去去去,赶紧睡觉!怎么就你事这么多?!” 19 | 20 | 一个个小朋友就这样被毁掉了,他们的好奇心就这样成了他们自己要主动避免的东西 —— 否则就会挨骂,谁愿意动不动就被一通数落呢? 21 | 22 | 好奇心是驱动一个人不断进步的最重要动力之一。所以必须不断呵护,呵护到老才对。 23 | 24 | 然而,就是这个如此金贵的东西,也会成为拖累;而且,若是真的被它拖累,那么最终真的会感觉非常遗憾,被好东西拖累 —— 太可惜了。 25 | 26 | 刚才所描述的,还只不过是两个小时而已的 “损失”。事实上,被注意力漂移所拖累的人,损失肯定远不止如此。在做 “工程” 或者 “项目” 的时候 —— 尤其是那种非实物类的工程或项目,比如,写个书,写个软件之类的 —— 注意力漂移导致的结果就是: 27 | 28 | > 时间不断流逝,可是工程却永远没有结果。 29 | 30 | 这种损失,完全是任何正常人都没办法承受的…… 这话其实并不准,因为事实上据我观察,绝大多数人受到这种拖累的结果,自己其实无法想象 —— 因为永远没有完成过什么项目,永远没有完成过什么工程,又如何知道自己损失的究竟是什么呢? 31 | 32 | 到今天为止,我自己依然还是个需要不断与 “注意力漂移” 争斗的人 —— 许多年前,我注意到这个现象的时候,经过思考,就接受了一个事实: 33 | 34 | > 注意力漂移不是能杜绝的现象,但必须在关键时刻有所应对…… 35 | 36 | 如果当年的我没认真想过这事,没思索出对策,那么后来的我也不可能写那么多书,转行那么多次,自学那么多大大小小的技能…… 当然,各位读者也完全看不到现在正在阅读的文字 —— 因为它们不可能被完整地写出来,甚至干脆就不应该存在。 37 | 38 | 在罗列并比较众多策略之后,我选了一个看起来最不相干,却最本质的策略: 39 | 40 | > **把 “全面完整” 放到最高优先级。** 41 | 42 | 而后,这些年全靠这个策略挺了过来…… 43 | 44 | 当我想做什么事的时候,或者想学什么东西的时候,我会投入一定的时间去琢磨,这个事或者这个东西,要做得全面完整,或者要学得全面完整,那都应该做什么呢?在思考如此严肃的问题的时候,我还是习惯用纸和笔,写写画画 —— 迄今为止没有找到合适的电子设备和软件替代。 45 | 46 | 我买笔记本,不是为了记笔记的,因为记笔记这个东西,实在是在电脑上做更方便,许多年前开始就是如此了。我的笔记本主要用来做一件事: 47 | 48 | > 罗列整理那些为了做到 “全面完整” 而必须优先做的事。 49 | 50 | 用列表也好、或者用图表也罢,反正都是要不断整理修订的,而它的存在,给了我一个优先级: 51 | 52 | > 除了这上面罗列的这些东西之外,在当前时间段,别的都不如它们重要。 53 | 54 | 一旦发现自己的注意力没有集中在这上面的关键之时,一旦发现自己的注意力已经漂移到其它当前并不重要的事项上,就马上纠正。 55 | 56 | 谁都知道应该先做重要且紧急的事情,可问题在于,如何判断 “是否重要” 呢?**全面完整**这四个字就会给我指引。 57 | 58 | 一方面,是用全面完整来保持自己对重要事情的关注,另外一方面,还需要提高对抗**不相关完美诱惑**的能力。十年前,我写《[把时间当作朋友](https://github.com/xiaolai/time-as-a-friend)》的时候,还把这东西叫做 “脆弱的完美主义倾向”,现在我已经把这个概念升级了 —— 因为更准确地讲,那不是 “完美主义者的脆弱”,那是 “能力不及格者” 的 “轻重不分”。 59 | 60 | 早些年,我跟很多人一样痴迷于电脑这个东西,也跟很多人那样,用 Windows 惯出来了坏毛病 —— 动不动就重装系统…… 重装系统很浪费时间的,但那时也不知道为什么总是忍不住去干那事,哪怕有些小毛病,马上就受不了,弄的好像重装一个干净的操作系统会让自己的世界焕然一新一样。 61 | 62 | 再后来就明白了,这绝对就是**自己的毛病 —— 做事不分轻重**。 63 | 64 | 说实话,这也不是自己想明白的 —— 我没那么聪明。是因为遇到了一个高人。他的电脑桌面上,乱七八糟摆满了各种图标,从不整理。我问他这不影响效率吗?他说,明明有搜索你不用,到底是谁效率低下?我被问愣了,无言以对。 65 | 66 | 我又发现他根本没有装杀毒软件…… 我问为什么?他说,“养几个虫子玩玩也没什么不好……” 不过,他转念又告诉了我他的思考。他说,只要平时习惯好,病毒进来了也没啥可偷的,但更为关键的是,他用电脑是干活的,而不是干杀毒的活的…… 脑子如此清楚,让我自愧不如。 67 | 68 | 但学到了。 69 | 70 | 虽然我还是做不到桌面上图标很乱,虽然我是因为改用了 Mac OS,所以不装杀毒软件,但注意力要放到应该放的地方,这事我记住了,牢牢记住,从此之后许多年,从未忘过。每次发现自己轻重不分的时候,就会想起他,然后就改过自新。 71 | -------------------------------------------------------------------------------- /markdown/R.finale.md: -------------------------------------------------------------------------------- 1 | 2 | # 自学者的终点 3 | 4 | …… 磨练自学手艺的你,早晚会遇到这种情况: 5 | 6 | > 必须学会一个没人教、没人带,甚至没有书可参考的技能。 7 | 8 | 这也许是我自己能够想象到的自学者所能经历的最高境界吧,因为那么多年过去之后的我也只不过走到这个地方而已…… 许多年过去,我通过自学习得的没有人教、没有人带、甚至没有书可参考的技能,很拿得出手的只有两个而已: 9 | 10 | > * 制作长销书 11 | > * 区块链投资 12 | 13 | 先说说区块链投资。 14 | 15 | 2011 年,我开始投资比特币的时候,不像现在。现在你能在 Amazon 上找到一大堆书,给你讲区块链技术、区块链投资…… 2011 年的时候,互联网这本大书上,连篇像样的文章都几乎没有。 16 | 17 | 在这样的领域里成为专家,其实比外界想象得容易 —— 当然,无论什么,外界总是觉得很难。为什么比外界想象得更容易呢?因为大家都不懂,仅此而已。 18 | 19 | 所以,剩下的事情很简单: 20 | 21 | > 谁能持续研究谁就可能更先成为专家。 22 | 23 | 到最后,还是一样的,决定因素在于有效时间投入,再次仅此而已。 24 | 25 | 了解我的人都知道,在知识技能的分享方面,我从来都没有 “藏着掖着” 的习惯。我说 “仅此而已” 的时候,那就是 “仅此而已”,没有任何其它保留。 26 | 27 | 说研读比特币白皮书,就真的研读,反复研读,每年都要重复若干遍 —— 有人问了,有那个必要吗?是哦,对我有没有那个必要,我自己说了算。并且,就算真有,告诉别人有什么用?对吧? 28 | 29 | > 这里是[《比特币白皮书》我翻译的版本](https://github.com/xiaolai/bitcoin-whitepaper-chinese-translation)。 30 | 31 | 说投资就真的投资,不是 “买两个试试”、“买几个玩玩” —— 我的做法是**重仓**。持仓之后继续研究,和两袖清风地读书研读肯定不一样。有一个与我极端相反的例子。此人大名鼎鼎,是《精通比特币》([Mastering Bitcoin](https://www.amazon.com/Mastering-Bitcoin-Programming-Open-Blockchain/dp/1491954388/))的作者,Andreas M. Antonopoulos,与我同岁,也是 1972 年生人。 32 | 33 | 他也是国外公认的比特币专家,但他不是投资人 —— 他几乎没有比特币。2017 年牛市的时候,人们听说大神 Andreas M. Antonopoulos 竟然几乎没有比特币,大为惊讶,向他捐款总计 102 个比特币左右 —— 千万不要误会我,我没有任何鄙视他的意思。这不是我说说而已,我是用行动支持他的人。他的书,《精通比特币》的中文版,还是我组织人翻译的。 34 | 35 | 我只是说,我和他不一样的地方在于,在某些方面我比他更实在,这也是事实。我相信我在实际投资后,对比特币也好区块链也罢,理解力会更深一些,因为驱动力不一样么,多简单的道理。 36 | 37 | 然而,仅仅 “谁能持续研究谁就更可能先成为专家” 这一条,其实并不够完成 “学会一个没人教、没人带,甚至没有书可参考的技能”。 38 | 39 | 这么多年来,我能够 “学会一些没人教、没人带,甚至没有书可参考的技能”(比如赚钱这事就是如此),更多的时候仰仗的是一个我已经告诉过你的 “秘密”…… 也许你想不起来了,但我一说你就能 “发现” 其实你真的[已经听我说过](Part.2.D.deliberate-thinking.md): 40 | 41 | > **刻意思考**:这东西我**还**能用在哪儿呢? 42 | 43 | 并且,我还讲过在自学编程的过程中,见识到的 MoSCoW Method 给我在写书方式上的影响。 44 | 45 | > 我写书就是这样的。在准备的过程中 —— 这个过程比绝大多数人想象得长很多 —— 我会罗列所有我能想到的相关话题…… 等我觉得已经再也没有什么可补充的时候,再为这些话题写上几句话构成的大纲…… 这时候就会发现很多话题其实应该是同一个话题。如此这般,一次扩张,一次收缩之后,就会进行下一步,应用 MoSCoW 原则,给这些话题打上标签 —— 在这过程中,总是发现很多之前感觉必要的话题,其实可以打上 `Won't have` 的标签,于是,把它们剔除,然后从 `Must have` 开始写起,直到 `Should have`,至于 `Could have` 看时间是否允许,看情况,比如,看有没有最后期限限制…… 46 | > 47 | > 在写书这事上,我总是给人感觉很快,事实上也是,因为有方法论 —— 但显然,那方法论不是从某一本 “如何写书” 的书里获得的,而是从另外一个看起来完全不相关的领域里习得后琢磨到的…… 48 | 49 | 你看,把另外一个领域里的知识拿过来用,是在一个 “没人教、也没人带,甚至没有书籍可供参考” 的领域中,最基本的生存技巧。 50 | 51 | 再进一步,当我们在最开始的时候说,“尽量只靠阅读习得一项新技能” 的时候,有一个重点现在终于在之前的很多解释与讲解之后能说清楚了: 52 | 53 | > 我们并不是不要老师这个角色了,准确地讲,我们只不过是不再需要 “传统意义上的老师” 了而已。 54 | 55 | 首先,我们把自己当作老师 —— 英文中,Self-teaching 这个词特别好,它描述得太准确了。很多的时候,想在身边找到好老师是很难的,甚至是不可能的。在这种情况下,我们没有别的选择,**我们只能把自己当作老师去教自己**。 56 | 57 | 其次,就算我们 100% 只依靠阅读,那内容不还是别人写的吗?写那内容的人,实际上就是老师。没错,书本,是历史上最早的远程教育形式,即便到今天也依然是最重要最有效的远程教学形式。阅读的好处在于,对老师的要求中没有地理位置的限制,若是能自由阅读英文,那就连国界限制都没有。“**书中自有颜如玉**” 这句话,显然是并不好色的人说的,因为他更爱书…… 这句话的意思其实是说: 58 | 59 | > 各路牛人都在书里…… 60 | 61 | 反正,写书的人群中,牛人比例相对较高,这是事实 —— 古今中外都一样。 62 | 63 | 进而,更为重要的是,一旦你把整个互联网当作一本大 “书”,把 Google 当作入口,实际发生的效果是: 64 | 65 | > 你把 “老师” 这个角色**去中心化**了…… 66 | 67 | 一方面 “老师” 这个角色的负担降低了,他们不用管你是谁,也不用管你怎么样了,他们该干嘛就干嘛;而另外一方面则对你更重要 —— 你学不同的东西,就可以找不同的老师;即便是相同的东西,你也可以找很多老师;对于任何一个老师,你都可以 “弱水三千只取一瓢”,也就是说,只挑他最厉害的部分去学…… 不就是多买几本书吗?不就是多搜索几次、多读一些文档吗? 68 | 69 | 最后,你竟然还有最厉害的一个小招数: 70 | 71 | > 无论学会什么,都要进一步**刻意思考**:这东西我**还**能用在哪儿呢? 72 | 73 | 于是,你 “一下子” 就升级了 —— 用这样的方式,相对于别人,你最可能 “学会几乎任何一个没人教、没人带,甚至没有书可参考的技能”…… 74 | 75 | 你看看自己的路径罢:从 “不得不把自己当作老师去教自己” 开始 —— 虽然起步是**不得不**,但这个 “不得不”,恰好是后来你变得更为强大的原因和起点…… 这就解释了为什么历史上有很多牛人的很多成就其实都是这样 “被迫” 获得的。 76 | 77 | 于是,我们终于可以好好总结一下了: 78 | 79 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/seflteaching-model.png?raw=true) 80 | 81 | > * 你一定要想办法启动自学,否则你没有未来; 82 | > * 你把自学当作一门手艺,长期反复磨练它; 83 | > * 你懂得学、练、用、造各个阶段之间的不同,以及针对每个阶段的对应策略; 84 | > * 面对 “过早引用” 过多的世界,你有你的应对方式; 85 | > * 你会 “囫囵吞枣”,你会 “重复重复再重复”,你深刻理解 “读书百遍其义自见”; 86 | > * 以后你最擅长的技能之一就是拆解拆解再拆解; 87 | > * 你用你的拆解手艺把所有遇到的难点都拆解成能搞定的小任务; 88 | > * 自学任何一门手艺之前你都不会去问 “有什么用”,而是清楚地知道,无论是什么只要学会了就只能也必然天天去用; 89 | > * 你没有刚需幻觉,你也没有时间幻觉,你更没有困难幻觉,反正你就是相对更清醒; 90 | > * 不管你新学什么手艺,你都知道只要假以时日你就肯定能做好,因为所有的手艺精湛,靠的只不过是充足的预算; 91 | > * 你知道如何不浪费生命,因为只要不是在刻意练习、不是在刻意思考,那就是在 “混时间”; 92 | > * 你总是在琢磨你能做个什么新作品; 93 | > * 你刻意地使用你的作品作为有效社交工具,也用作品去过滤无效社交; 94 | > * 你乐于分享,乐于阅读也更乐于写作 —— 因为这世界怎么帮助你的,你就想着要怎样回报; 95 | > * 你把全面和完整当作最高衡量标准,也用这个标准去克制、应对自己的注意力漂移; 96 | > * 你会不断自学新的手艺,因为你越来越理解单一技能的脆弱,越来越理解多项技能的综合威力; 97 | > * 你越来越依赖互联网,它是你最喜欢的 “书”,而 Google 是你最好的朋友 —— 他总是能帮你找到更好的老师; 98 | > * 偶尔,你会学会没人教、没人带、甚至没书可参考的手艺,别人都说你 “悟性” 高,可你自己清楚地知道那其实是怎么回事; 99 | > * 你越来越明白,其实没什么 “秘密”,越简单、越朴素的道理越值得重视; 100 | > * 你发现你用来思考的时间越来越多 —— 准确地讲,是 “琢磨”…… 只不过是因为你真会琢磨了 —— 你很清楚你应该花时间琢磨的是什么。 101 | 102 | 没有人教过我怎么写一本长销书(而不仅仅是畅销书),这显然是我通过自学习得的能力 —— 我也只能把自己当作老师教自己,这是不得已。然而,不得不的选择同样常常能给我带来好运…… 甚至,它也不是我通过阅读哪本书习得的能力 —— 因为这方面还真的没什么靠谱的书籍。然而,我竟然学会了 —— 靠什么?靠的就是上面说的那点事而已。 103 | 104 | “秘密” 是什么?说出来后,你听起来肯定是感觉 “太简单了” 乃至于 “有点不像真的”…… 每次,我都很认真的问自己以下几个问题: 105 | 106 | > * 我要写的内容,的确是正确的吗? 107 | > * 我要写的内容,确实会对读者有用吗? 108 | > * 有什么内容是必须有的、应该有的? 109 | > * 我写的这个内容,十年后人们再看,还会觉得跟新的一样有用嘛? 110 | > * 我的书名,就那么放在那里,会直接让买家产生不由自主购买的吸引力吗? 111 | 112 | 一旦这几个问题我有了清楚的答案,我就知道,我有能力制作一本新的长销书了 —— 真的没有什么别的 “秘密”。 113 | 114 | 在《通往财富自由之路》中,我分享过以下内容: 115 | 116 | > 我认为一个人的自学能力(当时还在用 “学习能力” 这个词)分为三个层次: 117 | > 1. 学会有人手把手教授的技能 118 | > 1. 学会书本上所教授的技能 119 | > 1. 学会没有人能教授的技能 120 | 121 | 这一次,我无非是把后两个层面用一个特大号的实例掰开了揉碎了讲清楚而已。 122 | 123 | 到最后,**没什么不能自学的,反正都只不过是手艺** —— 只不过,我们每个人都受限于自己的时间精力而已。所以,若是你正在读高一,正在读大一,那就好好珍惜自己有机会可以**随意设置充裕预算**的时光罢。若是你已为人父母,那就想办法用自己的行动影响下一代罢。然而,其实更为重要的是,无论什么时候,都要这么想: 124 | 125 | > 若是还有很长的未来,现在真不算晚…… 126 | 127 | 自学不过是一门手艺,而且还是谁都能掌握的。不要 “试试” 而已,而是 “直接开干” —— 这样才好。 128 | 129 | 最后还有个需要补充的是:很多人崇尚 “刻苦”,并且刻意强调其中的 “苦” —— 古训中所谓的 “吃得苦中苦,方为人上人” —— 这一点我并不认同,而且还是深刻地不认同。 130 | 131 | 我的观察是,所谓的 “苦”,是那些完全不会自学的人对自学者的所作所为的错误理解。 132 | 133 | 自学一点都不苦,道理也很简单: 134 | 135 | > 因为自学者是自发去学的,**原动力在于自己**。而不像其他人,是被动地学,原动力并非在于自己。 136 | 137 | 由于原动力在于自己,遇到困难时,当然同样苦恼;可不一样的是,有持续的原动力去克服那些困难,于是,总是在不断克服困难之后获得更大的愉悦、更大的满足感。 138 | 139 | 所以,“刻”,我们很认同,刻意地练习、刻意地思考,刻意地保持好奇心,刻意地去学习一些看起来与当前所掌握的手艺完全不相干的知识…… 至于 “苦” 么,那是别人的误解,我们自己开心着呢 —— 无所不在、无处诉说的幸福。 140 | 141 | **人生苦长,无需惊慌。** 142 | 143 | 祝你好运! 144 | 145 |

李笑来

146 |

初稿完成于 2019227

147 | 148 | -------------------------------------------------------------------------------- /markdown/S.whats-next.md: -------------------------------------------------------------------------------- 1 | 2 | # 下一步干什么? 3 | 4 | 理论上,下一步你的选择很多。自学是门手艺,你可以用它去学任何你想要掌握的其它手艺。如果,你有意在编程这个领域继续深入,那么,以下就是一些不错的线索。 5 | 6 | 当然,最先应当做的是,去检查一下自己的 “突击” 的结果,去 Pythonbasics.org 做做练习: 7 | 8 | > https://pythonbasics.org/Exercises/ 9 | 10 | 除了我在这里介绍的之外,请移步 The Hitchhiker's Guide to Python,它更为全面: 11 | 12 | > https://docs.python-guide.org/ 13 | 14 | ## Python 必读书籍 15 | 16 | 无论学什么,一本书肯定不够,以下是学习 Python 的基本必读书籍: 17 | 18 | > * [The Python Tutorial](https://docs.python.org/3/tutorial/) 19 | > * [The Hitchhiker's Guide to Python!](https://docs.python-guide.org/) 20 | > * [Think Python: How to think like a computer scientist](http://greenteapress.com/wp/think-python-2e/) 21 | > * [Automate the Boring Stuff with Python](https://automatetheboringstuff.com) 22 | > * [Effective Python](https://effectivepython.com) 23 | > * [Python Cookbook](https://www.amazon.com/Python-Cookbook-Recipes-Mastering-ebook/dp/B00DQV4GGY) 24 | > * [Fluent Python](https://www.amazon.com/Fluent-Python-Concise-Effective-Programming-ebook/dp/B0131L3PW4) 25 | > * [Problem Solving with Algorithms and Data Structures using Python](http://interactivepython.org/runestone/static/pythonds/index.html) 26 | > * [Mastering Object-oriented Python - Transform Your Approach to Python Programming](https://www.amazon.com/dp/B00JVQ14UO/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1) 27 | 28 | 更多 Python 书籍: 29 | 30 | > https://pythonbooks.revolunet.com 31 | 32 | 千万别觉得多,只要真的全面掌握,后面再学别的,速度上都会因此快出很多很多…… 33 | 34 | ## Python Cheatsheet 35 | 36 | 你已经知道了,这种东西,肯定是自己整理的才对自己真的很有用…… 不过,你也可以把别人整理的东西当作 “用来检查自己是否有所遗漏” 的工具。 37 | 38 | 网上有无数 Python Cheatsheets,以下是 3 个我个人认为相当不错的: 39 | 40 | > * [Comprehensive Python Cheatsheet](https://gto76.github.io/python-cheatsheet/) 41 | > * [Python Crash Course - Cheat Sheets](https://github.com/ehmatthes/pcc/tree/master/cheat_sheets) 42 | > * [Pysheeet](https://www.pythonsheets.com/) 43 | 44 | ## Awesome Python 45 | 46 | Github 上的 “居民” 现在已经养成了一个惯例,无论什么好东西,他们都会为其制作一个 “Awesome ...” 的页面,在里面齐心协力搜集相关资源。比如,你想学 Golang,那你去 Google 搜索 [`Awesome Go`](https://www.google.com/search?q=awesome+go),一定会给你指向到一个 Github 上的 “Awesome Go” 的页面…… 47 | 48 | 以下是 Awesome Python 的链接: 49 | 50 | > https://github.com/vinta/awesome-python 51 | 52 | ## CS 专业的人都在学什么? 53 | 54 | 如果你真有兴趣把这门手艺学精,不妨看看 Computer Science 专业的人都在学什么…… 55 | 56 | 下面这个链接值得认真阅读: 57 | 58 | > http://matt.might.net/articles/what-cs-majors-should-know/ 59 | 60 | ## 全栈工程师路径图 61 | 62 | 既然学了,就肯定不止 Python —— 在扎实的基础之上,学得越多学得越快。以下是一个 “全栈工程师路径图”,作者是位迪拜的帅哥 [Kamran Ahmed](https://github.com/kamranahmedse): 63 | 64 | > https://github.com/kamranahmedse/developer-roadmap 65 | > 66 | > Below you find a set of charts demonstrating the paths that you can take and the technologies that you would want to adopt in order to become a frontend, backend or a devops. I made these charts for an old professor of mine who wanted something to share with his college students to give them a perspective; sharing them here to help the community. 67 | > 68 | > Check out my blog and say "hi" on Twitter. 69 | > 70 | > **Disclaimer** 71 | > 72 | > The purpose of these roadmaps is to give you an idea about the landscape and to guide you if you are confused about what to learn next and not to encourage you to pick what is hip and trendy. You should grow some understanding of why one tool would better suited for some cases than the other and remember hip and trendy never means best suited for the job 73 | 74 | ## Introduction 75 | 76 | ![Web Developer Roadmap Introduction](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/intro.png?raw=true) 77 | 78 | ## Frontend Roadmap 79 | 80 | ![Frontend Roadmap](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/frontend.png?raw=true) 81 | 82 | ## Back-end Roadmap 83 | 84 | ![Back-end Roadmap](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/backend.png?raw=true) 85 | 86 | ## DevOps Roadmap 87 | 88 | ![DevOps Roadmap](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/devops.png?raw=true) 89 | 90 | 路漫漫其修远兮…… 91 | 92 | 但多有意思啊?这完全就是一场闯关游戏。 93 | -------------------------------------------------------------------------------- /markdown/T-appendix.editor.vscode.md: -------------------------------------------------------------------------------- 1 | 2 | # Visual Studio Code 的安装与配置 3 | 4 | 官方文档请查询: 5 | 6 | > https://code.visualstudio.com/docs 7 | 8 | ## 允许命令行启动 VS Code 9 | 10 | 使用快捷键 `⇧⌘p` 呼出 Command Palette,在其中输入 `shell command`,而后选中 `Install 'code' command in PATH`。此后,就可以在 Terminal 命令行中使用 `code` 命令了。(Windows 系统安装 VS Code 时会自动配置好,并不需要此步骤) 11 | 12 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/vscode-shell.png?raw=true) 13 | 14 | ## 选择 Python 解析器版本 15 | 16 | 使用快捷键 `⇧⌘p` 呼出 Command Palette,在其中输入 `select interpreter`,而后选中 `Python: Select Interpreter`。 17 | 18 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/vscode-select-python-version1.png?raw=true) 19 | 20 | 而后,在系统中已安装的若干个版本中选择你需要的那一个。MacOS 系统自带一个 Python 2.7,而我们安装的 Anaconda 为系统另外安装了一个 Python 3.7。 21 | 22 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/vscode-select-python-version2.png?raw=true) 23 | 24 | ## 安装扩展 25 | 26 | 使用快捷键 `⇧⌘x` 呼出扩展面板。安装 anaconda 扩展,它会连带装上 python 扩展: 27 | 28 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/vscode-extensions.png?raw=true) 29 | 30 | 另外,为了输入方便,有两个扩展可选安装: 31 | 32 | > * Tabout 有它之后,可以使用 TAB 键跳出光标后的括号、引号等等; 33 | > * Sublime Text Keymap and Settings Importer 有它之后,可以在 VS Code 中使用 SublimeText 的快捷键,最重要的当属多光标编辑 `⇧⌘l`…… 34 | 35 | ## 自动补全 36 | 37 | 专业编辑器最重要的功能之一,就是能够在你输入的时候它帮你做到 “自动补全”,通常使用的快捷键是 TAB 键 `⇥`。 38 | 39 | TAB 键 `⇥` 触发的自动补全有两种: 40 | 41 | > * 当前文件中已有的字符串。比如,之前你输入过 `sum_of_word`;那么,之后,你就可以输入 `su` 或者干脆 `sow` 而后按 TAB 键 `⇥`,“自动补全” 功能会帮你完成输入 `sum_of_word` 42 | > * 已有的 Snippets。比如,当你需要输入 `if ...: ...` 的时候,实际上当你输入 `if` 或者甚至 `i` 之后,你就可以用 TAB 键 `⇥`,“自动补全” 功能会为你 “自动完成” 语句块的输入。 43 | 44 | 字符串自动补全,使用的是所谓的 Fuzzy Match。输入 `sum_of_word` 中所包含的任意字符的任意组合(按顺序),它都会尽量去匹配;所以,`su` 和 `sow` 都可以匹配 `sum_of_word`,再比如,`rst` 可以匹配 `result`。 45 | 46 | 在 Snippet 自动补全的过程中,常常有若干个 “TAB Stop”,即,有若干个位置可以使用 TAB 键 `⇥`(或者,`Shift + ⇥`)来回切换;这时,第一种字符串自动补全的功能就失效了,如果需要使用字符串自动补全,那么需要按快捷键 ESC `⎋` 退出 Snippet 自动补全模式。 47 | 48 | 以下的 gif 文件演示的是以下代码的输入过程: 49 | 50 | ```python 51 | def sum_of_word(word): 52 | sum = 0 53 | for char in word: 54 | sum += ord(char) - 96 55 | return sum 56 | with open('results.txt', 'w') as results: 57 | with open('words_alpha.txt', 'r') as file: 58 | for word in file.readlines(): 59 | if sum_of_word(word.strip()) == 100: 60 | results.write(word) 61 | ``` 62 | 63 | 因为有这样的功能,所以你在输入程序的时候其实是非常从容的,可以很慢输入,边思考边输入…… 可实际上,完成速度却很快。 64 | 65 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/vscodedemo.gif?raw=true) 66 | 67 | 另外,SublimeText 的多光标输入是很多程序员爱不释手的功能,于是,各种编辑器里都有第三方写的 SublimeText Keymap 插件,连 Jupyterlab 都有: 68 | 69 | > https://github.com/ryantam626/jupyterlab_sublime 70 | -------------------------------------------------------------------------------- /markdown/T-appendix.symbols.md: -------------------------------------------------------------------------------- 1 | 2 | # 这些符号都代表什么? 3 | 4 | 以下的表格你可以用很多次 —— 每次学一门新语言的时候,都可以拿它整理一遍思路…… 5 | 6 | 最初的时候,人们能向计算机输入的只能是 ASCII 码表中的字符。于是从一开始,计算机科学家们就绞尽脑汁去琢磨怎么把这些符号用好、用足…… 7 | 8 | 于是,ASCII 码表中的字符常常在不同的地方有不同的用处。比如,`.`,在操作系统中,常常当作文件名和扩展名之间的分隔符;在很多编程语言中,都被当作调用 Class Attributes 和 Class Methods 的符号;在正则表达式中,`.` 代表除 `\r` `\n` 之外的任意字符…… 9 | 10 | 把下面的表格打印出来,整理一下,在表格里填写每个符号在 Python 中都是用来做什么的?[1] 11 | 12 | > 当前文件夹之中,有 `symbols.numbers` 文件,是用来打印以下表格的…… 13 | 14 | 以后不管学什么语言,就拿这个表格过一遍,到时候只有一个感觉:越学越简单! 15 | 16 | 很多人最初的时候学不进去,就是因为 “一些符号的用法太多了,经常混淆,于是就觉得累了、烦了……” 然而,只要多重复几次多在脑子里过几遍就熟悉了 —— 若是真的熟悉了、若是真的掌握了,你就会觉得:真的没什么啊!哪儿有那么难啊?! 17 | 18 | ![](https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/master/images/symbols.png?raw=true) 19 | 20 | 学编程的一个好玩之处就是: 21 | 22 | > 但凡你学会了任何一门编程语言,你就会发现你的键盘上的每一个键你都用得上…… 23 | 24 | 可是在此之前,你跟人家花了同样的价钱买来的硬件设备,你竟然有那么多根本就没用过的东西! 25 | 26 | 普通人花同样价钱买来的是台机器而已;可是你却不一样 —— 用同样的价钱买来的是一个特别听话的机器人,一个可以替你不分昼夜不辞辛苦干活的机器人 —— 这感觉非常神奇。 27 | 28 | ----- 29 | **脚注** 30 | 31 | [1]:Python 语法,请参阅 The Python Language Reference [2. Lexical analysis](https://docs.python.org/3/reference/lexical_analysis.html#operators) 32 | 33 | ↑Back to Content↑ 34 | -------------------------------------------------------------------------------- /markdown/TOC.md: -------------------------------------------------------------------------------- 1 | ## 自学是门艺术 2 | 3 | - [01 前言](01.preface.md) 4 | - [02 如何证明你真的读过这本书?](02.proof-of-work.md) 5 | 6 | ## PART 1 7 | 8 | - [Part.1.A 为什么一定要掌握自学能力?](Part.1.A.better.teachyourself.md) 9 | - [Part.1.B 为什么把编程当作自学的入口?](Part.1.B.why.start.from.learning.coding.md) 10 | - [Part.1.C 只靠阅读习得新技能](Part.1.C.must.learn.sth.only.by.reading.md) 11 | - [Part.1.D 开始阅读前的一些准备](Part.1.D.preparation.for.reading.md) 12 | - [Part.1.E.1 入口](Part.1.E.1.entrance.md) 13 | - [Part.1.E.2 值及其相应的运算](Part.1.E.2.values-and-their-operators.md) 14 | - [Part.1.E.3 流程控制](Part.1.E.3.controlflow.md) 15 | - [Part.1.E.4 函数](Part.1.E.4.functions.md) 16 | - [Part.1.E.5 字符串](Part.1.E.5.strings.md) 17 | - [Part.1.E.6 数据容器](Part.1.E.6.containers.md) 18 | - [Part.1.E.7 文件](Part.1.E.7.files.md) 19 | - [Part.1.F 如何从容应对含有过多 “过早引用” 的知识?](Part.1.F.deal-with-forward-references.md) 20 | - [Part.1.G 官方教程:The Python Tutorial](Part.1.G.The-Python-Tutorial-local.md) 21 | 22 | ## PART 2 23 | 24 | - [Part.2.A 笨拙与耐心](Part.2.A.clumsy-and-patience.md) 25 | - [Part.2.B 刻意练习](Part.2.B.deliberate-practicing.md) 26 | - [Part.2.C 为什么从函数开始?](Part.2.C.why-start-from-writing-functions.md) 27 | - [Part.2.D.1 关于参数(上)](Part.2.D.1-args.md) 28 | - [Part.2.D.2 关于参数(下)](Part.2.D.2-aargs.md) 29 | - [Part.2.D.3 化名与匿名](Part.2.D.3-lambda.md) 30 | - [Part.2.D.4 递归函数](Part.2.D.4-recursion.md) 31 | - [Part.2.D.5 函数的文档](Part.2.D.5-docstrings.md) 32 | - [Part.2.D.6 保存到文件的函数](Part.2.D.6-modules.md) 33 | - [Part.2.D.7 测试驱动的开发](Part.2.D.7-tdd.md) 34 | - [Part.2.D.8 可执行的 Python 文件](Part.2.D.8-main.md) 35 | - [Part.2.E 刻意思考](Part.2.E.deliberate-thinking.md) 36 | 37 | ## PART 3 38 | 39 | - [Part.3.A 战胜难点](Part.3.A.conquering-difficulties.md) 40 | - [Part.3.B.1 类 —— 面向对象编程](Part.3.B.1.classes-1.md) 41 | - [Part.3.B.2 类 —— Python 的实现](Part.3.B.2.classes-2.md) 42 | - [Part.3.B.3 函数工具](Part.3.B.3.decorator-iterator-generator.md) 43 | - [Part.3.B.4 正则表达式](Part.3.B.4.regex.md) 44 | - [Part.3.B.5 BNF 以及 EBNF](Part.3.B.5.bnf-ebnf-pebnf.md) 45 | - [Part.3.C 拆解](Part.3.C.breaking-good-and-bad.md) 46 | - [Part.3.D 刚需幻觉](Part.3.D.indispensable-illusion.md) 47 | - [Part.3.E 全面 —— 自学的境界](Part.3.E.to-be-thorough.md) 48 | - [Part.3.F 自学者的社交](Part.3.F.social-selfteaching.md) 49 | - [Part.3.G 这是自学者的黄金时代](Part.3.G.the-golden-age-and-google.md) 50 | - [Part.3.H 避免注意力漂移](Part.3.H.prevent-focus-drifting.md) 51 | 52 | ## 附章 53 | 54 | - [Q 如何成为优秀沟通者](Q.good-communiation.md) 55 | - [R 自学者的终点](R.finale.md) 56 | - [S 下一步干什么?](S.whats-next.md) 57 | 58 | ## 附录 59 | 60 | - [Appendix A: Visual Studio Code 的安装与配置](T-appendix.editor.vscode.md) 61 | - [Appendix B: Git 简介](T-appendix.git-introduction.md) 62 | - [Appendix C: Jupyterlab 的安装与配置](T-appendix.jupyter-installation-and-setup.md) 63 | - [Appendix D: 这些符号都代表什么?](T-appendix.symbols.md) 64 | -------------------------------------------------------------------------------- /my-notes/how-to-merge.md: -------------------------------------------------------------------------------- 1 | # Github进行fork后如何与原仓库同步 2 | 3 | 实在是……有太多人同时在帮忙修订错别字或优化 xiaolai 的 `the-craft-of-selfteaching` 了。如果你提交的 pull request 未被接受且得到回复说:“重新fork”,其实是你遇到一个问题: 4 | 5 | > * 在你 fork 之后, xiaolai 的仓库又更新了; 6 | > * 但 github 不会自动帮你把 xiaolai 的仓库同步给你 fork 后的仓库; 7 | > * 导致你提交 pull request 时的版本和 xiaolai 的版本不一致。 8 | 9 | 这个问题,用显得更“专业”的说法,叫做:`Github进行fork后如何与原仓库同步 `。那到底怎么做呢? 10 | 11 | 最省事的办法可能是: 12 | 13 | > * 在你fork的仓库setting页翻到最下方,然后delete这个仓库; 14 | > * 然后重新fork xiaolai 的仓库,并 git clone 到你的本地。 15 | 16 | 有时候,你需要用到这个省事的办法,比如 xiaolai 的仓库再次整理了 commit ;或者你已经玩坏了自己fork的仓库,又或者你所提交的大量内容仅是个人练习,但对 xiaolai 并无帮助—— 于是如果你就这样提交 pull request 会有大量无效内容吖,只能删了重来。 17 | 18 | 但在更多情况下,删掉自己fork的库,应该是你的最后选择,而不应该是首选。 19 | 20 | 和很多人一起向 xiaolai 提交 pull request,这实在是一个反复练习 `merge` (中文说法:合并,或版本合并)的机会。毫不夸张地讲,版本管理是软件工程极其重要的规范,也是极其基础的必备技能。而 `merge` 则是版本管理中最必须也最常用的场景。 21 | 22 | 那要不然,就多练练?以下是傻瓜版操作步骤,还细心配了截图,保管你从 0 也能上手。至于原理嘛,慢慢再搞懂吧。 23 | 24 | ### merge前的设定 25 | 26 | step 1、进入到本地仓库的目录。 27 | 28 | 下面所有操作,如无特别说明,都是在你的本地仓库的目录下操作。比如我的本地仓库为 `/from-liujuanjuan-the-craft-of-selfteaching` 29 | 30 | ![image](https://user-images.githubusercontent.com/31027645/54422899-6938e880-474a-11e9-8768-27ac24673e28.png) 31 | 32 | 33 | step 2、执行命令 `git remote -v` 查看你的远程仓库的路径: 34 | 35 | ![image](https://user-images.githubusercontent.com/31027645/54422975-95ed0000-474a-11e9-96bf-1018d6bc06f2.png) 36 | 37 | 如果只有上面2行,说明你未设置 `upstream` (中文叫:上游代码库)。一般情况下,设置好一次 `upstream` 后就无需重复设置。 38 | 39 | step 3、执行命令 `git remote add upstream https://github.com/selfteaching/the-craft-of-selfteaching.git` 把 xiaolai 的仓库设置为你的 `upstream` 。这个命令执行后,没有任何返回信息;所以再次执行命令 `git remote -v` 检查是否成功。 40 | 41 | ![image](https://user-images.githubusercontent.com/31027645/54423107-d8aed800-474a-11e9-9ab8-7bb901181283.png) 42 | 43 | step 4、执行命令 `git status` 检查本地是否有未提交的修改。如果有,则把你本地的有效修改,先从本地仓库推送到你的github仓库。最后再执行一次 `git status` 检查本地已无未提交的修改。 44 | 45 | `git add -A` 或者 `git add filename` 46 | `git commit -m "your note"` 47 | `git push origin master` 48 | `git status` 49 | 50 | 注1:作为新手,这一步建议严格执行,是为了避免大量无效修改或文本冲突带来的更复杂局面。 51 | 52 | 注2:如果你已经在fork后的仓库提交了大量对 xiaolai 的仓库并没有价值的修改,那么想要pull request,还是重新回到本文最初的“最省事办法”吧。 53 | 54 | 55 | ### merge 的关键命令 56 | 57 | 以下操作紧接着上面的步骤。 58 | 59 | step 5、执行命令 `git fetch upstream` 抓取 xiaolai 原仓库的更新: 60 | 61 | ![image](https://user-images.githubusercontent.com/31027645/54448734-60b2d300-4787-11e9-9fdf-90fcc2e66052.png) 62 | 63 | step 6、执行命令 `git checkout master` 切换到 master 分支: 64 | 65 | ![image](https://user-images.githubusercontent.com/31027645/54448759-6dcfc200-4787-11e9-8bbc-a5beef23ea88.png) 66 | 67 | step 7、执行命令 `git merge upstream/master` 合并远程的master分支: 68 | 69 | ![image](https://user-images.githubusercontent.com/31027645/54449526-47128b00-4789-11e9-9add-09217eb91a68.png) 70 | 71 | 72 | step 8、执行命令 `git push ` 把本地仓库向github仓库(你fork到自己名下的仓库)推送修改 73 | 74 | 如果担心自己不小心改了哪里,可以再次执行命令 `git status` 检查哪些文件有变化。这个操作仅是检查,不会改变任何状态,放心用。 75 | 76 | ![image](https://user-images.githubusercontent.com/31027645/54449665-a07aba00-4789-11e9-9181-bdcc814fffe6.png) 77 | 78 | 79 | 现在你已经解决了fork的仓库和原仓库版本不一致的问题。可以放心向 xiaolai 发起 pull request 了。如果以上操作你花了不少时间,而 xiaolai 的仓库又恰好更新了。很好,一次新的练习机会来了…… 80 | 81 | -------------------------------------------------------------------------------- /my-notes/老生常谈的思考: -------------------------------------------------------------------------------- 1 | 笑来讲一切自学都是老生常谈 2 | 那么就是说我们其实所有的学习方式在学校的时候已经学会了。整理归纳总结,朗读,重复的朗读,重复的练习,重复的做一切都已经是学过的。没有什么新鲜的事情。 3 | 关键在于PRACTICE MAKES PERFECT看谁练习的次数,看谁阅读的书更多,看谁的见识更广,看谁练习的更多,当然还有用正确的方法做正确的事情。 4 | 如果方法不能够保证,至少要保证做的事情是正确的。 5 | 那么我们小时候是不是爱好学习的呢?答案是,肯定的,小时候观察蚂蚁运动几个小时,学习说话那么多次的重复,学习拿碗筷等等,我们都有自学的能力,且爱学的。 6 | 那么我们是从几岁开始就不爱学习了呢?是从学习就是坐在板凳上练习小提琴,是坐在桌子上做作业,是背诵课文,是父母或者老师要求的事物,一切都是以考试为中心的时候, 7 | 我们对于学习这件事情,开始日复一日的反感,开始为了保持自己思维的独立性而反抗,最后把好的不好的都丢了,一部分学习优异的孩子学到了,但毕业以后却厌倦了, 8 | 最后也把他们给丢弃了,学习不好的孩子更是早早的就把它们丢弃了。 9 | 笑来老师的自学是门手艺,其实是对于点燃学习兴趣的一点星星之火,把他当做一门手艺,不需要什么智商,也没有什么门槛,就是一门手艺且熟能生巧。 10 | -------------------------------------------------------------------------------- /my-notes/自学笔记--emhodo.md: -------------------------------------------------------------------------------- 1 | # 摘抄:(道理模块) 2 | ## 前言 3 | One has no future if one couldn't teach themself 4 | > - 至少有 99% 的人终生都没有掌握自学能力 5 | > - 应试教育的确是磨灭自学能力的最有效方法 6 | > - 焦虑不是被卖方贩卖的产品,焦虑其实是买方长期自行积累的结果。别人无法贩卖给你焦虑,是你自己焦虑 —— 是你自己在为自己不断积累越来越多的焦虑。**但自学能力强的人不焦虑,起码他们不会因为学习以及学习过程而焦虑 —— 这是重大差别。** 7 | > - 生活质量就是这样一点一点被消磨掉的 —— 最消耗生活质量的东西,就是焦虑。 8 | > - 讲大道理的更可能是庸者、失败者,而不是成功者。 9 | > - 不仅讨厌老生常谈,而且偏要对着干,干着干着就把自己变成了另外一个属于那 99% 的另外一个老生……这是 99% 的人终其一生的生动写照。 10 | > - 在自学这件事上,重视一切老生常谈…… 11 | > - 自学没有什么 “秘诀”。它是一门手艺,并且,严格意义上来讲,它只是一门手艺。 12 | > - 手艺的特点就是无需天分。手艺的特点就是熟练程度决定一切。从这一点上来看,自学这门手艺和擀饺子皮没什么区别 —— 就那点事,刚开始谁都笨手笨脚,但熟练了之后,就那么回事…… 而已。(**全书精华**) 13 | ## 如何证明你真的读过这本书? 14 | 更朴素一点,更接近真相的解释是: 15 | > - 那百分之七八十的人,其实是想着给自己一个希望…… 16 | —— 等我有空了一定看。嗯。 17 | 说来好笑,其实每个人共同拥有的目标之一是这样的: 18 | 成为前百分之二十的少数人…… 19 | 然而,PK 掉百分之七八十的人的方法真的很简单很简单啊: 20 | 把买来的书都真真切切地认真读过就可以了。 21 | 这实在是太简单了罢?!可是…… 我知道你刚刚那个没出息的闪念: 22 | 那我少买书甚至不买书不就可以了吗? 23 | 你自己都知道这是荒谬的,却忍不住为你的小聪明得意 —— 其实吧,幸亏有你们在,否则我们怎么混进前百分之二十呢? 24 | **太真实了······** 25 | > - 比特币这个地球上第一个真正被证明为可行的区块链应用中有一个特别重要的概念,叫做 “工作证明”(Proof of Work)—— 你干活了就是干活了,你没干活就是没干活,你的工作是可被证明的…… 26 | 证明的方法是使用 github.com 这个网站以及版本控制工具 git。(**本来这篇笔记是写在石墨文档上的,因为重复阅读、总结梳理的时候看到这里,竟然发现之前看的那一遍竟然没注意到这个细节,甚至之前好多细节都没注意到,所以反复阅读,重复阅读,及时总结梳理是多么的重要啊!**) 27 | 编程入门的门槛之所以高,有个比较特殊的原因:它的知识点结构不是线性的。 28 | - 前置引用:想要理解当前的知识点,需要依赖对以后才能开始学习的知识点的深入理解。 29 | - 学编程中最重要的活动就是 “阅读官方文档”。学 Python 更是如此。 30 | - 有能力只靠阅读就能习得新技能。 31 | - 自己生活工作学习上遇到的所有疑问,书本里应该都有答案 —— 起码有所参考。 32 | - 绝大多数情况下,没人能教你,也不一定有人愿意教你…… 到最后,你想学会或你必须学会什么东西的时候,你只能靠阅读! —— 因为其实你谁都靠不上…… 33 | -------------------------------------------------------------------------------- /my-notes/自学笔记(python篇)--emhodo.md: -------------------------------------------------------------------------------- 1 | > - `random.randrange(1,1000)`表示随机产生一个1-1000的整数(含左侧1,但不含右侧1000)。 2 | > - `for in range(10)` 将0-9依次遍历到i 3 | 4 | 案例1:打印出100以内的所有质数。 5 | 6 | ` 7 | for i in range (2,100): 8 | 9 | 10 | ` 11 | -------------------------------------------------------------------------------- /mycode.py: -------------------------------------------------------------------------------- 1 | def is_prime(n): 2 | """ 3 | Return a boolean value based upon 4 | whether the argument n is a prime number. 5 | """ 6 | if n < 2: 7 | return False 8 | if n == 2: 9 | return True 10 | for m in range(2, int(n**0.5)+1): 11 | if (n % m) == 0: 12 | return False 13 | else: 14 | return True 15 | 16 | def say_hi(*names, greeting='Hello', capitalized=False): 17 | """ 18 | Print a string, with a greeting to everyone. 19 | :param *names: tuple of names to be greeted. 20 | :param greeting: 'Hello' as default. 21 | :param capitalized: Whether name should be converted to capitalzed before print. False as default. 22 | :returns: None 23 | """ 24 | for name in names: 25 | if capitalized: 26 | name = name.capitalize() 27 | print(f'{greeting}, {name}!') -------------------------------------------------------------------------------- /regex-target-text-sample.txt: -------------------------------------------------------------------------------- 1 |
    2 |
  1. begin began begun begins beginning
  2. 3 |
  3. google gooogle goooogle goooooogle
  4. 4 |
  5. coloured color coloring  colouring colored
  6. 5 |
  7. never ever verb however everest
  8. 6 |
  9. 520 52000 5200000 520000000 520000000000
  10. 7 |
  11. error wonderer achroiocythaemia achroiocythemia
  12. 8 |
  13. The white dog wears a black hat.
  14. 9 |
  15. Handel, Händel, Haendel
  16. 10 |
11 |
(843) 542-4256
(431) 270-9664
12 |
3336741162
3454953965
13 |
    14 |
  • peoplesr@live.com
  • jaxweb@hotmail.com
  • 15 |
  • dhwon@comcast.net
  • krueger@me.com
  • 16 |
17 |

URLs

18 | https://docs.python.org/3/howto/regex.html 19 | https://docs.python.org/3/library/re.html 20 |

passwords

21 | Pasw0rd~ 22 | i*Eh,GF67E 23 | a$4Bh9XE&E 24 |

duplicate words

25 |

It's very very big.

26 |

Keep it simple, simple, simple!

-------------------------------------------------------------------------------- /symbols.numbers: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/symbols.numbers -------------------------------------------------------------------------------- /test-file.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/selfteaching/the-craft-of-selfteaching/38b0bcaed3743fdee25bb5b3d75f522f49a4b93f/test-file.txt -------------------------------------------------------------------------------- /that.py: -------------------------------------------------------------------------------- 1 | def main(): 2 | 3 | s = """Gur Mra bs Clguba, ol Gvz Crgref 4 | Ornhgvshy vf orggre guna htyl. 5 | Rkcyvpvg vf orggre guna vzcyvpvg. 6 | Fvzcyr vf orggre guna pbzcyrk. 7 | Pbzcyrk vf orggre guna pbzcyvpngrq. 8 | Syng vf orggre guna arfgrq. 9 | Fcnefr vf orggre guna qrafr. 10 | Ernqnovyvgl pbhagf. 11 | Fcrpvny pnfrf nera'g fcrpvny rabhtu gb oernx gur ehyrf. 12 | Nygubhtu cenpgvpnyvgl orngf chevgl. 13 | Reebef fubhyq arire cnff fvyragyl. 14 | Hayrff rkcyvpvgyl fvyraprq. 15 | Va gur snpr bs nzovthvgl, ershfr gur grzcgngvba gb thrff. 16 | Gurer fubhyq or bar-- naq cersrenoyl bayl bar --boivbhf jnl gb qb vg. 17 | Nygubhtu gung jnl znl abg or boivbhf ng svefg hayrff lbh'er Qhgpu. 18 | Abj vf orggre guna arire. 19 | Nygubhtu arire vf bsgra orggre guna *evtug* abj. 20 | Vs gur vzcyrzragngvba vf uneq gb rkcynva, vg'f n onq vqrn. 21 | Vs gur vzcyrzragngvba vf rnfl gb rkcynva, vg znl or n tbbq vqrn. 22 | Anzrfcnprf ner bar ubaxvat terng vqrn -- yrg'f qb zber bs gubfr!""" 23 | 24 | d = {} 25 | for c in (65, 97): 26 | for i in range(26): 27 | d[chr(i+c)] = chr((i+13) % 26 + c) 28 | 29 | print("".join([d.get(c, c) for c in s])) 30 | 31 | 32 | if __name__ == '__main__': 33 | main() --------------------------------------------------------------------------------