笨方法学python(练习题)
参考:笨办法学 Python (Learn Python The Hard Way)中文版
习题 0: 准备工作
总有一天你会听到有程序员建议你使用 Mac OSX 或者 Linux。如果他喜欢字体美观,他会告诉你让你弄台 Mac OSX 计算机,如果他们喜欢操作控制而且留了一部大胡子,他会让你安装 Linux。这里再次向你说明,只要是一台手上能用的电脑就可以了。你需要的只有三样东西: gedit、一个命令行终端、还有python。
习题 1: 第一个程序
学会看调试错误
这些内容你应该学会看懂的,这是很重要的一点,因为你以后还会犯类似的错误。就是我现在也会犯这样的错误。让我们一行一行来看。
python
- 会打印出错误的行
- 指示错误的地方
- 指示错误的类型
习题 2: 注释和井号
程序里的注释是很重要的。它们可以用自然语言告诉你某段代码的功能是什么。 在你想要临时移除一段代码时,你还可以用注解的方式将这段代码临时禁用.
习题 3: 数字和数学计算
每一种编程语言都包含处理数字和进行数学计算的方法。不必担心,程序员经常撒谎说他们是多么牛的数学天才,其实他们根本不是。
如果他们真是数学天才,他们早就去从事数学相关的行业了,而不是写写广告程序和社交网络游戏,从人们身上偷赚点小钱而已。
习题 4: 变量(variable)和命名
在编程中,变量只不过是用来指代某个东西的名字。 程序员通过使用变量名可以让他们的程序读起来更像英语。 而且因为程序员的记性都不怎么地. 变量名可以让他们更容易记住程序的内容。如果他们没有在写程序时使用好的变量名,在下一次读到原来写的代码时他们会大为头疼的
习题 5: 更多的变量和打印
- 格式化字符串(format string)
- 试着使用更多的格式化字符。例如 %r 就是是非常有用的一个,它的含义是“不管什么都打印出来”。
习题 6: 字符串(string)和文本
字符串可以包含格式化字符 %s,这个你之前也见过的。你只要将格式化的变量放到字符串中,再紧跟着一个百分号 % (percent),再紧跟着变量名即可。
唯一要注意的地方,是如果你想要在字符串中通过格式化字符放入多个变量的时候,你需要将变量放到 ( ) 圆括号(parenthesis)中,而且变量之间用 ,逗号(comma)隔开。就像你逛商店说“我要买牛奶、面包、鸡蛋、八宝粥”一样,只不过程序员说的是”(milk, eggs, bread, soup)”。
习题 7: 更多打印
- 从现在开始,把你的错误记录下来,写在一张纸上。
- 在开始下一节习题时,阅读一遍你记录下来的错误,并且尽量避免在下个练习中再犯同样的错误。
- 记住,每个人都会犯错误。程序员和魔术师一样,他们希望大家认为他们从不犯错,不过这只是表象而已,他们每时每刻都在犯错。
习题 8: 打印,打印
习题 9: 打印,打印,打印
习题 10: 那是什么
- 使用反斜杠 \ (back-slash) 可以将难打印出来的字符放到字符串。针对不同的符号有很多这样的所谓“转义序列(escape sequences)”.
- 但有一个特殊的转义序列,就是 双反斜杠(double back-slash) \\ 。这两个字符组合会打印出一个反斜杠来.
tabby_cat = "\tI'm tabbed in." #\t制表符
persian_cat = "I'm split\non a line." #\n换行符
backslash_cat = "I'm \\ a \\ cat." #2个\\显示1个\
fat_cat = """
I'll do a list:
\t* Cat food
\t* Fishies
\t* Catnip\n\t* Grass
"""
print tabby_cat
print persian_cat
print backslash_cat
print fat_cat
输出:
I'm tabbed in.
I'm split
on a line.
I'm \ a \ cat.
I'll do a list:
* Cat food
* Fishies
* Catnip
* Grass
习题 11: 提问
一般软件做的事情主要就是下面几条:
- 接受人的输入。
- 改变输入。
- 打印出改变了的输入。
注意到我在每行 print 后面加了个逗号(comma) , 了吧?这样的话 print 就不会输出新行符而结束这一行跑到下一行去了。
习题 12: 提示别人
习题 13: 参数、解包、变量
- 在第 1 行我们有一个“import”语句. 这是你将 python 的功能引入你的脚本的方法.
- Python 不会一下子将它所有的功能给你,而是让你需要什么就调用什么。
- 这样可以让你的程序保持精简,而后面的程序员看到你的代码的时候,这些“import”可以作为提示,让他们明白你的代码用到了哪些功能。
from sys import argv
script, first, second, third = argv
print ("The script is called:") , script
print ("Your first variable is:") , first
print ("Your second variable is:") , second
print ("Your third variable is:") , third
在pycharm里面运行命令行: Run/Debug Configurations->Configurations->Script Parames
输出:
The script is called:
F:/2���/python/nesterjerrychan/chapter6/learnhardway/test.py
Your first variable is: first
Your second variable is: second
Your third variable is: third
习题 14: 提示和传递
习题 15: 读取文件
我使用了“命令”这个词,不过实际上它们的名字是“函数(function)”和“方法(method)。上网搜索一下这两者的意义和区别。看不明白也没关系,迷失在别的程序员的知识海洋里是很正常的一件事情。
习题 16: 读写文件
- close – 关闭文件。跟你编辑器的 文件->保存.. 一个意思。
- read – 读取文件内容。你可以把结果赋给一个变量。
- readline – 读取文本文件中的一行。
- truncate – 清空文件,请小心使用该命令。
- write(stuff) – 将stuff写入文件。
习题 17: 更多文件操作
文本1--->复制文本--->文本2 为什么每次需要output.close()?
1.把文件想象成信件就可以了,打开信封才能取出信纸,把信纸放入信封还要封好,不然随时可能掉出来.
2.如果没有close(),写入的内容可能会存在缓冲区中,并没有真正的写入文件里。
3.close()是为了释放资源。 如果不close(),那就要等到垃圾回收时,自动释放资源。垃圾回收的时机是不确定的,也无法控制的。 如果程序是一个命令,很快就执行完了,那么可能影响不大(注意:并不是说就保证没问题)。 但如果程序是一个服务,或是需要很长时间才能执行完,或者很大并发执行,就可能导致资源被耗尽,也有可能导致死锁。
习题 18: 命名、变量、代码、函数
函数可以做三样事情:
- 它们给代码片段命名,就跟“变量”给字符串和数字命名一样。
- 它们可以接受参数,就跟你的脚本接受 argv一样。
- 通过使用 #1 和 #2,它们可以让你创建“微型脚本”或者“小命令”。
创建函数过程:
- 告诉 Python 创建一个函数,def ,也就是“定义(define)”的意思。
- 紧接着 def 的是函数的名称。但最好函数的名称能够体现出函数的功能来。
习题 19: 函数和变量
函数里边的变量和脚本里边的变量之间是没有连接的
习题 20: 函数和文件
习题 21: 函数可以返回东西
习题 22: 到现在你学到了哪些东西?
做这节练习没有失败,只有尝试,请牢记这一点。
习题 23: 读代码
习题 24: 更多练习
习题 25: 更多更多的练习
当你成为程序员以后,你将需要经常面对别的程序员的代码,也许还有他们的傲慢态度,他们会经常说自己的代码是完美的。
这样的程序员是自以为是不在乎别人的蠢货。优秀的科学家会对他们自己的工作持怀疑态度,同样,优秀的程序员也会认为自己的代码总有出错的可能,他们会先假设是自己的代码有问题,然后用排除法清查所有可能是自己有问题的地方,最后才会得出“这是别人的错误”这样的结论。
习题 26: 恭喜你,现在可以考试了!
习题 27: 记住逻辑关系
逻辑术语
在 python 中我们会用到下面的术语(字符或者词汇)来定义事物的真(True)或者假(False)。
计算机的逻辑就是在程序的某个位置检查这些字符或者变量组合在一起表达的结果是真是假。
and
与or
或not
非!=
(not equal) 不等于==
(equal) 等于>=
(greater-than-equal) 大于等于<=
(less-than-equal) 小于等于True
真False
假
真值表
记住一点,这本书不会要求你成功或者失败,只要每天尽力去学,在尽力的基础上多花一点功夫就可以了。
习题 28: 布尔表达式练习
习题 29: 如果(if)
习题 30: Else 和 If
你认为 if 对于它下一行的代码做了什么?
- If 语句为代码创建了一个所谓的“分支”,就跟 RPG 游戏中的情节分支一样。
- if 语句告诉你的脚本:“如果这个布尔表达式为真,就运行接下来的代码,否则就跳过这一段。
为什么 if 语句的下一行需要 4 个空格的缩进?
- 行尾的冒号的作用是告诉 Python 接下来你要创建一个新的代码区段。这根你创建函数时的冒号是一个道理。
如果不缩进, 会发生什么事情?
- Python 的规则里,只要一行以“冒号(colon)” : 结尾,它接下来的内容就应该有缩进。
习题 31: 作出决定
习题 32: 循环和列表
习题 33: While 循环
如果你的某一行是以 : (冒号, colon)结尾,那就意味着接下来的内容是一个新的代码片段,新的代码片段是需要被缩进的。
只有将代码用这样的方式格式化,Python 才能知道你的目的。
使用while要注意的事项:
- 尽量少用 while-loop,大部分时候 for-loop 是更好的选择。
- 重复检查你的 while 语句,确定你测试的布尔表达式最终会变成 False 。
- 如果不确定,就在 while-loop 的结尾打印出你要测试的值。看看它的变化。
习题 34: 访问列表的元素
最好的解释方式是将你平时使用数字的方式和程序员使用数字的方式做对比。
假设你在观看上面列表中的四种动物(['bear', 'tiger', 'penguin', 'zebra']) 的赛跑,而它们比赛的名词正好跟列表里的次序一样。
这是一场很激动人心的比赛,因为这些动物没打算吃掉对方,而且比赛还真的举办起来了。结果你的朋友来晚了,他想知道谁赢了比赛,他会问你“嘿,谁是第 0 名”吗?不会的,他会问“嘿,谁是第 1 名?”
这是因为动物的次序是很重要的。没有第一个就没有第二个,没有第二个也没有第三个。第零个是不存在的,因为零的意思是什么都没有。“什么都没有”怎么赢比赛嘛,完全不合逻辑。
这样的数字我们称之为“序数(ordinal number)”,因为它们表示的是事物的顺序。
而程序员不能用这种方式思考问题,因为他们可以从列表的任何一个位置取出一个元素来。
对程序员来说,上述的列表更像是一叠卡片。如果他们想要 tiger,就抓它出来,如果想要zebra,也一样抓取出来。要随机地抓取列表里的内容,列表的每一个元素都应该有一个地址,或者一个 “index(索引)”,而最好的方式是使用以 0 开头的索引。
相信我说的这一点吧,这种方式获取元素会更容易。这类的数字被称为“基数(cardinal number)”,它意味着你可以任意抓取元素,所以我们需要一个 0 号元素。
那么,这些知识对于你的列表操作有什么帮助呢?
很简单,每次你对自己说“我要第 3 只动物”时,你需要将“序数”转换成“基数”,只要将前者减 1 就可以了。第 3 只动物的索引是 2,也就是 penguin。
由于你一辈子都在跟序数打交道,所以你需要用这种方式来获得基数,只要减 1 就都搞定了。
- 记住: ordinal == 有序,以 1 开始;cardinal == 随机选取, 以 0 开始。
习题 35: 分支和函数
习题 36: 设计和调试
If 语句的规则:
- 每一个“if 语句”必须包含一个 else.
- 如果这个 else 永远都不应该被执行到,因为它本身没有任何意义,那你必须在 else 语句后面使用一个叫做 die 的函数,让它打印出错误信息并且死给你看,
- “if 语句”的嵌套不要超过 2 层,最好尽量保持只有 1 层。
- 这意味着如果你在 if 里边又有了一个 if,那你就需要把第二个 if 移到另一个函数里面。
- 将“if 语句”当做段落来对待,其中的每一个 if, elif, else 组合就跟一个段落的句子组合一样。在这种组合的最前面和最后面留一个空行以作区分。
- 你的布尔测试应该很简单,如果它们很复杂的话,你需要将它们的运算事先放到一个 变量里,并且为变量取一个好名字。
如果你遵循上面的规则,你就会写出比大部分程序员都好的代码来。
循环的规则:
- 只有在循环永不停止时使用“while 循环”,这意味着你可能永远都用不到。这条只有 Python 中成立,其他的语言另当别论。
- 其他类型的循环都使用“for 循环”,尤其是在循环的对象数量固定或者有限的情况下。
调试(debug)的小技巧:
- 不要使用 “debugger”。 Debugger 所作的相当于对病人的全身扫描。你并不会得到某方面的有用信息,而且你会发现它输出的信息态度,而且大部分没有用,或者只会让你更困惑。
- 最好的调试程序的方法是使用 print 在各个你想要检查的关键环节将关键变量打印出来,从而检查哪里是否有错。
- 让程序一部分一部分地运行起来。不要等一个很长的脚本写完后才去运行它。写一点,运行一点,再修改一点。
建议:
每一个程序员在开始一个新的大项目时,都会被非理性的恐惧影响到。为了避免这种恐惧,他们会拖延时间,到最后一事无成。我有时会这样,每个人都会有这样的经历,避免这种情况的最好的方法是把自己要做的事情列出来,一次完成一样。
开始做吧。
先做一个小一点的版本,扩充它让它变大,把自己要完成的事情一一列出来,然后逐个完成就可以了。
习题 37: 复习各种符号
Keywords(关键字):
- and
- del
- from
- not
- while
- as
- elif
- global
- or
- with
- assert
- else
- if
- pass
- yield
- break
- except
- import
- class
- exec
- in
- raise
- continue
- finally
- is
- return
- def
- for
- lambda
- try
数据类型
- True
- False
- None
- strings
- numbers
- floats
- lists
字符串转义序列(Escape Sequences)
\\
\'
\"
\a
\b
\f
\n
\r
\t
\v
字符串格式化(String Formats)
%d
%i
%o
%u
%x
%X
%e
%E
%f
%F
%g
%G
%c
%r
%s
%%
操作符号
+
-
*
**
/
//
%
<
>
<=
>=
==
!=
<>
( )
[ ]
{ }
@
,
:
.
=
;
+=
-=
*=
/=
//=
%=
**=
习题 38: 阅读代码
然后通读你打印出来的代码并做好标记,标记的内容包括以下几个方面:
- 函数以及函数的功能。
- 每个变量的初始赋值。
- 每个在程序的各个部分中多次出现的变量。它们以后可能会给你带来麻烦。
- 任何不包含 else 的 if 语句。它们是正确的吗?
- 任何可能没有结束点的 while 循环。
- 最后一条,代码中任何你看不懂的部分都记下来。
习题 39: 列表的操作
当你看到像 mystuff.append('hello')
这样的代码时,你事实上已经在 Python 内部激发了一个连锁反应。以下是它的工作原理:
- Python 看到你用到了
mystuff
,于是就去找到这个变量。也许它需要倒着检查看你有没有在哪里用=
创建过这个变量,或者检查它是不是一个函数参数,或者看它是不是一个全局变量。不管哪种方式,它得先找到 mystuff 这个变量才行。 - 一旦它找到了
mystuff
,就轮到处理句点.
(period) 这个操作符,而且开始查看mystuff
内部的一些变量了。由于mystuff
是一个列表,Python 知道mystuff
支持一些函数。 - 接下来轮到了处理
append
。Python 会将“append”
和mystuff
支持的所有函数的名称一一对比,如果确实其中有一个叫append
的函数,那么Python
就会去使用这个函数。 - 接下来 Python 看到了括号 并且意识到, “噢,原来这应该是一个函数”,到了这里,它就正常会调用这个函数了,不过这里的函数还要多一个参数才行。
- 这个额外的参数其实是……
mystuff
! 我知道,很奇怪是不是?不过这就是 Python 的工作原理,所以还是记住这一点,就当它是正常的好了。真正发生的事情其实是append(mystuff, 'hello')
,不过你看到的只是mystuff.append('hello')
。
习题 40: 字典, 可爱的字典
这是最有用的容器:字典(dictionary)。
Python 将这种数据类型叫做 “dict”,有的语言里它的名称是 “hash”。
针对列表你可以使用数字作为列表的索引,也就是你可以通过数字找到列表中的元素
而 dict 所作的,是让你可以通过任何东西找到元素,不只是数字。
是的,字典可以将一个物件和另外一个东西关联,不管它们的类型是什么
cities = {'CA': 'San Francisco', 'MI': 'Detroit',
'FL': 'Jacksonville'}
cities['NY'] = 'New York'
cities['OR'] = 'Portland'
def find_city(themap, state):
if state in themap:
return themap[state]
else:
return "Not found."
# ok pay attention!
cities['_find'] = find_city
while True:
print "State? (ENTER to quit)",
state = raw_input("> ")
if not state: break
# this line is the most important ever! study!
city_found = cities['_find'](cities, state)
print city_found
习题 41: 来自 Percal 25 号行星的哥顿人(Gothons)
cities['_find'] = find_city
city_found = cities['_find'](cities, state)
#相当于city_found = find_city(cities, state)
python运行原理:
- Python 看到 city_found = 于是知道了需要创建一个变量。
- 然后它读到 cities ,然后知道了它是一个字典
- 然后看到了 ['_find'] ,于是 Python 就从索引找到了字典 cities 中对应的位置,并且获取了该位置的内容。
- ['_find'] 这个位置的内容是我们的函数 find_city ,所以 Python 就知道了这里表示一个函数,于是当它碰到
(
就开始了函数调用。 - cities, state 这两个参数将被传递到函数 find_city 中,然后这个函数就被运行了。
- find_city 接着从 cities 中寻找 states ,并且返回它找到的内容,如果什么都没找到,就返回一个信息说它什么都没找到。
- Python find_city 接受返回的信息,最后将该信息赋值给一开始的 city_found 这个变量。
倒着阅读:
- state 和 city 是...
- 作为参数传递给...
- 一个函数,位置在...
- '_find' 然后寻找,目的地为...
- cities 这个位置...
- 最后赋值给 city_found.
由里向外的读法:
- 找到表达式的中心位置,此次为 ['_find'].
- 逆时针追溯,首先看到的是一个叫 cities 的字典,这样就知道了 cities 中的 _find 元素。
- 上一步得到一个函数。继续逆时针寻找,看到的是参数。
- 参数传递给函数后,函数会返回一个值。然后再逆时针寻找。
- 最后,我们到了 city_found = 的赋值位置,并且得到了最终结果。
下面三种读代码的方法,它们适用于几乎所有的编程语言:
- 从前向后。
- 从后向前。
- 逆时针方向。
习题 42: 物以类聚
虽说将函数放到字典里是很有趣的一件事情,你应该也会想到“如果 Python 能自动为你做这件事情该多好”。事实上也的确有,那就是 class
这个关键字。你可以使用 class
创建更棒的“函数字典”
Class(类)有着各种各样强大的功能和用法,但本书不会深入讲这些内容,在这里,你只要你学会把它们当作高级的“函数字典”使用就可以了。
用到class
的编程语言被称作“Object Oriented Programming(面向对象编程)”语言。这是一种传统的编程方式,你需要做出“东西”来,然后你“告诉”这些东西去完成它们的工作。
已做过类似的事情
stuff = ['Test', 'This', 'Out']
print ' '.join(stuff)
其实你这里已经使用了 class。stuff 这个变量其实是一个 list class (列表类)。
而 ' '.join(stuff)
里调用函数 join 的字符串 ' '
(就是一个空格)也是一个 class —— 它是一个 string class (字符串类)。到处都是 class!
你看到参数里的 self 了吧?你知道它是什么东西吗?对了,它就是 Python 创建的额外的一个参数,有了它你才能实现 a.some_function()
这种用法,这时它就会把\ 前者翻译成 ``some_function(a) 执行下去。
为什么用 self 呢?
- 因为你的函数并不知道你的这个“实例”是来自叫 TheThing 或者别的名字的 class。所以你只要使用一个通用的名字 self。这样你写出来的函数就会在任何情况下都能正常工作。
__init__
函数- 这就是你为 Python class 设置内部变量的方式
习题 43: 你来制作一个游戏
编程就是解决问题的过程,这就意味着你要尝试各种可能性,进行实验,经历失败,然后丢掉你做出来的东西重头开始。当你被某个问题卡住的时候,你可以向别人寻求帮助,并把你的代码贴出来给他们看。如果有人刻薄你,别理他们,你只要集中精力在帮你的人身上就可以了。持续修改和清理你的代码,直到它完整可执行为止,然后再研究一下看它还能不能被改进。
习题 44: 给你的游戏打分
函数的风格:
- 由于各种各样的原因,程序员将 class (类)里边的函数称作 method (方法)
- 在你使用 class 的过程中,很大一部分时间是告诉你的 class 如何“做事情”。给这些函数命名的时候,与其命名成一个名词,不如命名为一个动词,作为给 class 的一个命令。
- 就和 list 的 pop (抛出)函数一样,它相当于说:“嘿,列表,把这东西给我 pop 出去。”它的名字不是 remove_from_end_of_list ,因为即使它的功能的确是这样,这一串字符也不是一个命令。
- 让你的函数保持简单小巧
类的风格:
- 你的 class 应该使用 “camel case(驼峰式大小写)”,例如你应该使用 SuperGoldFactory 而不是 super_gold_factory。
- 你的
__init__
不应该做太多的事情,这会让 class 变得难以使用。 你的其它函数应该使用 “underscore format(下划线隔词)"
- 所以你可以写 my_awesome_hair,
- 而不是 myawesomehair 或者 MyAwesomeHair 。
用一致的方式组织函数的参数
- 不要对全局变量或者来自模块的变量进行重定义或者赋值,让这些东西自顾自就行了。
不要一根筋式地维持风格一致性,这是思维力底下的妖怪喽啰做的事情。一致性是好事情,不过愚蠢地跟着别人遵从一些白痴口号是错误的行为——这本身就是一种坏的风格。好好为自己照想把。
永远永远都使用
class Name(object)
的方式定义 class,否则你会碰到大麻烦。
代码风格:
- 为了以方便他人阅读,为自己的代码字符之间留下一些空白。你将会看到一些很差的程序员,他们写的代码还算通顺,但字符之间没有任何空间。这种风格在任何编程语言中都是坏习惯.
- 人的眼睛和大脑会通过空白和垂直对齐的位置来扫描和区隔视觉元素,如果你的代码里没有任何空白,这相当于为你的代码上了迷彩装。
- 如果一段代码你无法朗读出来,那么这段代码的可读性可能就有问题。如你找不到让某个东西易用的方法,试着也朗读出来。这样不仅会逼迫你慢速而且真正仔细阅读过去,还会帮你找到难读的段落,从而知道那些代码的易读性需要作出改进。
- 学着模仿别人的风格写 Python 程序,直到哪天你找到你自己的风格为止。
- 一旦你有了自己的风格,也别把它太当回事。程序员工作的一部分就是和别人的代码打交道,有的人审美就是很差。相信我,你的审美某一方面一定也很差,只是你从未意识到而已。
- 如果你发现有人写的代码风格你很喜欢,那就模仿他们的风格。
好的注释:
- 有程序员会告诉你,说你的代码需要有足够的可读性,这样你就无需写注释了。他们会以自己接近官腔的声音说“所以你永远都不应该写代码注释。”这些人要么是一些顾问型的人物,如果别人无法使用他们的代码,就会付更多钱给他们让他们解决问题。要么他们能力不足,从来没有跟别人合作过。别理会这些人,好好写你的注解。
- 写注解的时候,描述清楚为什么你要这样做。代码只会告诉你“这样实现”,而不会告诉你“为什么要这样实现”,而后者比前者更重要。
- 当你为函数写文档注解的时候,记得为别的代码使用者也写些东西。你不需要狂写一大堆,但一两句话谢谢这个函数的用法还是很有用的。
- 最后要说的是,虽然注解是好东西,太多的注解就不见得是了。而且注解也是需要维护的,你要尽量让注解短小精悍一语中的,如果你对代码做了更改,记得检查并更新相关的注解,确认它们还是正确的。
经常写到后面就懒得去维护注释了,有些注释是写到后面已经没用了,如果别人阅读我的代码估计会被带偏。
习题 45: 对象、类、以及从属关系
类(class)”和“对象(object)”的区别。问题在于,class 和 object 并没有真正的不同。它们其实是同样的东西,只是在不同的时间名字不同罢了。
老程序员的建议
在这么久的旅程下来我的体会是:编程语言这东西并不重要,重要的是你用这些语言做的事情。事实上我一直知道这一点,不过以前我会周期性地被各种编程语言分神而忘记了这一点。现在我是永远不会忘记这一点了,你也不应该忘记这一点。
你学到和用到的编程语言并不重要。不要被围绕某一种语言的宗教把你扯进去,这只会让你忘掉了语言的真正目的,也就是作为你的工具来实现有趣的事情。
编程作为一项智力活动,是唯一一种能让你创建交互式艺术的艺术形式。你可以创建项目让别人使用,而且你可以间接地和使用者沟通。没有其他的艺术形式能做到如此程度的交互性。电影领着观众走向一个方向,绘画是不会动的。而代码却是双向互动的。
技术公司里边会编程的人多到一毛钱一打,根本得不到什么尊敬。而在生物学、医药学、政府部门、社会学、物理学、数学等行业领域从事编程的人就能得到足够的尊敬,而且你可以使用这项技能在这些领域做出令人惊异的成就。