- Learn Python The Hard Way (笨办法学Python) 你会学到如何去: 在全平台上安装Python环境。
- 官网, Learn Python the Hard Way 。
- 书, Learn Python 3 the Hard Way: A Very Simple Introduction to the Terrifyingly Beautiful World of Computers and Code (Zed Shaw’s Hard Way Series): 9780134692883: Computer Science Books @ Amazon.com 。
- 免费html版本, Learn Python the Hard Way 。
通过将本书里的每一个例子一字不差地打出来,你将通过实践训练自己,让自己集中 精力到你作品的细节上面。
虽然对这点我不苟同。
Copyright (C) 2010 by Zed A. Shaw. 你可以在不收取任何费用,而且不修改任何内容 的前提下自由分发这本书给任何人。但是本书的内容只允许完整原封不动地进行分发和传 播。也就是说如果你用这本书给人上课,只要你不向学生收费,而且给他们看的书是完整 未加修改的,那就没问题。
准备工作
这里先说Win7
的,OSX
的之后再说。
开始打开PowerShell
,开始打开Python
了,输入python
小写。
退出python
的方法是Ctrl
+z
再回车,回到上面那一步的操作。
现在的问题是无法复制命令框的代码。
Powershell复制历史命令 - PowerShell 中文博客 但是不是非常直接。
在CMD命令行和PowerShell中实现复制粘贴功能 - 系统技巧 - 次元立方网 - 电脑知识与技术互动交流平台 这篇文章解释了这个底层问题。
在Powershell顶端右键\(\to\)编辑,可以查看到复制
是灰色的,表示默认,并且发现快捷方式是回车键,因此只要用鼠标,点击左键,选中代码框中需要的代码,然后点击回车,代码就复制好了。
PS C:\Users\lijiaxiang> cd myfolder
PS C:\Users\lijiaxiang\myfolder>
… 使用 Notepad++
编辑 myfolder
目录下的 test.txt
…
PS C:\Users\lijiaxiang\myfolder> ls
目录: C:\Users\lijiaxiang\myfolder
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a--- 2018/1/10 16:56 4 test.txt
在OSX
中安装TextWrangler
TextWrangler is now part of BBEdit. We have sunsetted TextWrangler, and BBEdit has changed to make room for TextWrangler users.
因此安装,BBEdit
好麻烦,直接用微软的Visual Studio Code好了。
习题1: python xxx.py
print("Hello World!")
print("Hello Again")
print("I like typing this.")
print("this is fun.")
print('Yay! Printing.')
print("I'd much rather you 'not'.")
print('I "said" do not touch this.')
这是Python的代码,注意,"
和'
是相互套用。
PS C:\Users\lijiaxiang\myfold
Hello World!
Hello Again
I like typing this.
this is fun.
Yay! Printing.
I'd much rather you 'not'.
I "said" do not touch this.
习题3: 运算符号
print("I will now count my chickens:")
print("Hens", 25 + 30/6)
print("Roosters", 100 - 25 * 3 % 4)
print("Now I will count the eggs:")
print(3 + 2 + 1 - 5 + 4 % 2 - 1/4 + 6)
print("Is it true that 3 + 2 < 5 -7?")
print(3+2<5-7)
print("What is 3+2?", 3+2)
print("WHat is 5-7?", 5-7)
print("Oh, that's why it's False.")
print("How about some more.")
print("Is it greater?", 5 > -2)
print("Is it greater or equal?", 5 >= -2)
print("Is it less or equal?", 5 <= -2)
%
的解释。
返回除法的余数。
PS C:\Users\lijiaxiang\myfolder> python ex3.py
I will now count my chickens:
Hens 30.0
Roosters 97
Now I will count the eggs:
6.75
Is it true that 3 + 2 < 5 -7?
False
What is 3+2? 5
WHat is 5-7? -2
Oh, that's why it's False.
How about some more.
Is it greater? True
Is it greater or equal? True
Is it less or equal? False
习题4: 变量
cars = 100
space_in_a_car = 4.0
drivers = 30
passengers = 90
cars_not_driven = cars - drivers
cars_driven = drivers
carpool_capacity = cars_driven * space_in_a_car
average_passengers_per_car = passengers / cars_driven
print("There are", cars, "cars available.")
print("There are only", drivers, "drivers available.")
print("There will be", cars_not_driven, "empty cars today.")
print("We can transport", carpool_capacity, "people today.")
print("We have", passengers, "to carpool today.")
print("We need to put about", average_passengers_per_car, "in each car.")
PS C:\Users\lijiaxiang\myfolder> python ex4.py
There are 100 cars available.
There are only 30 drivers available.
There will be 70 empty cars today.
We can transport 120.0 people today.
We have 90 to carpool today.
We need to put about 3.0 in each car.
习题5: 字符串的变量
#
是注释。
%s
是字符串的变量。通过% variable
来衡量。
可以用(var1, var2)
来完成两个变量的引用。
my_name = 'Zed A. Shaw'
my_age = 35 # not a lie
my_height = 74 # inches
my_weight = 180 # lbs
my_eyes = 'Blue'
my_teeth = 'White'
my_hair = 'Brown'
print("Let's talk about %s." % my_name)
print("He's %d inches tall." % my_height)
print("He's %d pounds heavy." % my_weight)
print("Actually that's not too heavy.")
print("He's got %s eyes and %s hair." % (my_eyes, my_hair))
print("His teeth are usually %s depending on the coffee." % my_teeth)
# this line is tricky, try to get it exactly right
print("If I add %d, %d, and %d I get %d." % (
my_age, my_height, my_weight, my_age + my_height + my_weight))
PS C:\Users\lijiaxiang\myfolder> python ex5.py
Let's talk about Zed A. Shaw.
He's 74 inches tall.
He's 180 pounds heavy.
Actually that's not too heavy.
He's got Blue eyes and Brown hair.
His teeth are usually White depending on the coffee.
If I add 35, 74, and 180 I get 289.
习题6: %
和打印
x = "There are %d types of people." % 10
binary = "binary"
do_not = "don't"
y = "Those who know %s and those who %s." % (binary, do_not)
print(x)
print(y)
print("I said: %r." % x)
print("I also said: '%s'." % y)
hilarious = False
joke_evaluation = "Isn't that joke so funny?! %r"
print(joke_evaluation % hilarious)
w = "This is the left side of..."
e = "a string with a right side."
print(w + e)
注意这里
y = "Those who know %s and those who %s." % (binary, do_not)
y
可以直接这样定义。
PS C:\Users\lijiaxiang\myfolder> python ex6.py
There are 10 types of people.
Those who know binary and those who don't.
I said: 'There are 10 types of people.'.
I also said: 'Those who know binary and those who don't.'.
Isn't that joke so funny?! False
This is the left side of...a string with a right side.
习题8: %r
的认识
The
%s
specifier converts the object usingstr()
, and%r
converts it usingrepr()
.
%r
更像是raw data。
举例,
months = "\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug"
print("Here are the months: %r" % months)
print("Here are the months: %s" % months)
PS C:\Users\lijiaxiang\myfolder> python .\ex7_pre.py
Here are the months: '\nJan\nFeb\nMar\nApr\nMay\nJun\nJul\nAug'
Here are the months:
Jan
Feb
Mar
Apr
May
Jun
Jul
Aug
%r
真的会把\n
打印出来。
习题10: """
和\t
的使用
tabby_cat = "\tI'm tabbed in."
persian_cat = "I'm split\non a line."
backslash_cat = "I'm \\ a \\ cat."
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)
学习这个地方\t
的使用方法。
并且在Notepad++
中,有很好的树结构,如图。
PS C:\Users\lijiaxiang\myfolder> python ex10.py
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: input()
和调查问卷
任何软件处理数据都是 input\(\to\) transform\(\to\) output 。
每行 print
后面加了个逗号 ,
了吧?这样的话 print
就不会输出新行符而结束这一行跑到下一行去了。
print("How old are you?",
age = raw_input())
print("How tall are you?",
height = raw_input())
print("How much do you weigh?",
weight = raw_input())
print("So, you're %r old, %r tall and %r heavy." % (age, height, weight))
实际上,我没有看懂raw_input
中间为什么是空的。
英文版我也没太看得懂,所以现在来说,这个问题先过了。
我明白了,其实这个就是个调查问卷的讨论。
f
的功能就是替代了.format()
了,看下面的例子。
a = "Hello"
b = "World"
print(f"{a} {b}")
print(f"{a + ' ' + b}")
之后看英文版,中文版本有点老了。
PS C:\Users\lijiaxiang\myfolder> python .\ex11.py
How old are you?
一个个的问问题,回答24
PS C:\Users\lijiaxiang\myfolder> python .\ex11.py
How old are you? 24
How tall are you?
接着问,
PS C:\Users\lijiaxiang\myfolder> python .\ex11.py
How old are you? 24
How tall are you? Alex
How much do you weigh?
接着问,
PS C:\Users\lijiaxiang\myfolder> python .\ex11.py
How old are you? 24
How tall are you? Alex
How much do you weigh? 80
So, you're 24 old, Alex tall and 80 heavy.
并且,x = int(input())
保证输出是数字,可以进行运算。
用到的书,
习题12:
苹果自带的软件不能复制粘贴书上的文字,太渣了。
Exercise 12. Prompting People
就是说input
要给点提示,
如y = input("Name?")
。
age = input("How old are you? ")
height = input("How tall are you? ")
weight = input("How much do you weigh? ")
这样就不需要单独领出来"How old are you? "
来print了。
age = input("How old are you? ")
height = input("How tall are you? ")
weight = input("How much do you weigh? ")
print(f"So, you're {age} old, {height} tall and {weight} heavy."
这里不work,换了这个
# print(f"So, you're {age} old, {height} tall and {weight} heavy.")
print("So , you're %r old, %r tall and %r heavy." %(age, height, weight ))
但是实际上,
"How old are you? "
也会print出来的。
$ python ex12.py
How old are you? 24
How tall are you? 185
How much do you weigh? 80
So , you're '24' old, '185' tall and '80' heavy.
Exercise 13. Parameters, Unpacking, Variables
What’s the difference between
argv
andinput()
? The difference has to do with where the user is required to give input. If they give your script inputs on the command line, then you useargv.
If you want them to input using the keyboard while the script is running, then useinput()
.
这里就解释了两者东西在取舍时的条件。
from sys import argv
# read the WYSS section for how to run this
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)
$ python ex13.py a b c
The script is called: ex13.py
Your first variable is: a
Your second variable is: b
Your third variable is: c
所以这里a b c
可以是不一样的。
Exercise 14. Prompting and Passing
from sys import argv
script, user_name = argv
prompt = 'answer: '
print(f"Hi {user_name}, I'm the {script} script.")
print("I'd like to ask you a few questions.")
print(f"Do you like me {user_name}?")
likes = input(prompt)
print(f"Where do you live {user_name}?")
lives = input(prompt)
print("What kind of computer do you have?")
computer = input(prompt)
print(f"""
Alright, so you said {likes} about liking me.
You live in {lives}. Not sure where that is.
And you have a {computer} computer. Nice.
""")
$ python ex14.py jiaxiang
Hi jiaxiang, I'm the ex14.py script.
I'd like to ask you a few questions.
Do you like me jiaxiang?
answer: 1
Where do you live jiaxiang?
answer: 1
What kind of computer do you have?
answer: 1
Alright, so you said 1 about liking me.
You live in 1. Not sure where that is.
And you have a 1 computer. Nice.
思考中间有什么骚操作没有?
我回答了名字、yes、住址、电脑。
但是代码实现的阶段是。
只不过input这里相当于加了个前缀、符号而已,不加只用input()
也可以的。
Exercise 15. Reading Files
pydoc open
这里pydoc
相当于help
,open
相当于某个要查询的函数。
这里类似于read_*
in R。
实际上,
.read()
是已经内置的read功能函数。
from sys import argv
script, filename = argv
mytxt = open(filename)
print(f"Here's your file {filename}: ")
print(mytxt.read())
print("Type the filename again: ")
myfile_again = input("> ")
mytxt_again = open(myfile_again)
print(mytxt_again.read())
注意这里第一个input,通过命令完成,
python ex15.py ex15_sample.txt
。
第二个通过,input()
。
$ python ex15.py ex15_sample.txt
Here's your file ex15_sample.txt:
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
Type the filename again:
> ex15_sample.txt
This is stuff I typed into a file.
It is really cool stuff.
Lots and lots of fun to have in here.
Exercise 16. Reading and Writing Files
好无聊,明天再弄。
You only need to remember that
write
takes a parameter of a string you want to write to the file.
这个地方开始设计一个程序了。
from sys import argv
script, filename = argv
print(f"We're going to erase {filename}.")
print("If you don't want that, hit CTRL-C (^C).")
print("If you do want that, hit RETURN.")
这个地方的反馈是非常easy的,就是{filename}
类似于%r
的。
w
代表以写的方式打开一个文件。
不然这里没办法t.truncate()
。
input("?")
print("Opening the file...")
target = open(filename, 'w')
line1 = input("line 1: ")
line2 = input("line 2: ")
line3 = input("line 3: ")
print("I'm going to write these to the file.")
target.write(line1)
target.write("\n")
target.write(line2)
target.write("\n")
target.write(line3)
target.write("\n")
print("And finally, we close it.")
target.close()
输出:
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> python .\ex16.py test.txt
We're going to erase test.txt.
If you don't want that, hit CTRL-C (^C).
If you do want that, hit RETURN.
?
Opening the file...
Now I'm going to ask you for three lines.
line 1: 1
line 2: 2
line 3: 3
I'm going to write these to the file.
And finally, we close it.
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> cat .\test.txt
1
2
3
'w' open for writing, truncating the file first
但是实际上不需要.truncate
的。
用python -m pydoc open
查看。
可以测试这一点。
# target.truncate()
掉,看看。
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> python .\ex16.py test.txt
We're going to erase test.txt.
If you don't want that, hit CTRL-C (^C).
If you do want that, hit RETURN.
?
Opening the file...
Truncating the file. Goodbye!
Now I'm going to ask you for three lines.
line 1: 11
line 2: 22
line 3: 33
I'm going to write these to the file.
And finally, we close it.
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> cat .\test.txt
11
22
33
真的是啊,那怎么办?仅仅是修改不行吗?
\(\Box\)不好查。
Exercise 17. Copy Files
书上的代码有问题,做了两处修改。
str(indata)
,因为wirte
的时候,不是str
的。
open(from_file,'rb')
写的时候,不是utf-8
,这里加上'rb'
(
python - UnicodeDecodeError: ‘utf8’ codec can’t decode byte 0xa5 in position 0: invalid start byte - Stack Overflow
)。
from sys import argv
from os.path import exists # verify the existence of a file.
script, from_file, to_file = argv
print(f"Copying from {from_file} to {to_file}")
# we could do these two on one line, how?
in_file = open(from_file,'rb')
indata = in_file.read()
# open(from_file).read()
print(f"The input file is {len(indata)} bytes long")
print(f"Does the output file exist? {exists(to_file)}")
print("Ready, hit RETURN to continue, CTRL-C to abort.")
input()
out_file = open(to_file, 'w')
out_file.write(str(indata))
print("Alright, all done.")
out_file.close()
in_file.close()
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> echo "This is a test file." > test1.txt
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> cat .\test1.txt
This is a test file.
PS C:\Users\lijiaxiang\Downloads\trans\myfolder> python .\ex17.py .\test1.txt test2.txt
Copying from .\test1.txt to test2.txt
The input file is 46 bytes long
Does the output file exist? True
Ready, hit RETURN to continue, CTRL-C to abort.
Alright, all done.
Exercise 18. Names, Variables, Code, Functions
写function,就是用def
。
What does the
*
in*args
do? That tells Python to take all the arguments to the function and then put them inargs
as a list. It’s likeargv
.
# this one is like your scripts with argv
def print_two(*args):
arg1, arg2 = args
print(f"arg1: {arg1}, arg2: {arg2}")
这里别忘了缩进,Python对缩进很敏感。
# ok, that *args is actually pointless, we can just do this
def print_two_again(arg1, arg2):
print(f"arg1: {arg1}, arg2: {arg2}")
# this just takes one argument
def print_one(arg1):
print(f"arg1: {arg1}")
# this one takes no arguments
def print_none():
print("I got nothin'.")
print_two("Zed","Shaw")
print_two_again("Zed","Shaw")
print_one("First!")
print_none()
结果为
IndentationError: expected an indented block
PS C:\Users\lijiaxiang\Downloads\归档\trans\myfolder> python .\ex18.py
arg1: Zed, arg2: Shaw
arg1: Zed, arg2: Shaw
arg1: First!
I got nothin'.
Exercise 19. Functions and Variables
这里f
类似于.format()
。
def cheese_and_crackers(cheese_count, boxes_of_crackers):
print(f"You have {cheese_count} cheeses!")
print(f"You have {boxes_of_crackers} boxes of crackers!")
print("Man that's enough for a party!")
print("Get a blanket.\n")
print("We can just give the function numbers directly:")
cheese_and_crackers(20, 30)
print("OR, we can use variables from our script:")
amount_of_cheese = 10
amount_of_crackers = 50
cheese_and_crackers(amount_of_cheese, amount_of_crackers)
print("We can even do math inside too:")
cheese_and_crackers(10 + 20, 5 + 6)
print("And we can combine the two, variables and math:")
cheese_and_crackers(amount_of_cheese + 100, amount_of_crackers)
注意def
的时候,不要忘记缩进。
> python .\ex19.py
We can just give the function numbers directly:
You have 20 cheeses!
You have 30 boxes of crackers!
Man that's enough for a party!
Get a blanket.
OR, we can use variables from our script:
You have 10 cheeses!
You have 50 boxes of crackers!
Man that's enough for a party!
Get a blanket.
We can even do math inside too:
You have 30 cheeses!
You have 11 boxes of crackers!
Man that's enough for a party!
Get a blanket.
And we can combine the two, variables and math:
You have 110 cheeses!
You have 50 boxes of crackers!
Man that's enough for a party!
Get a blanket.
Exercise 20. Functions and Files
回忆Exercise 13,$ python ex13.py a b c
,因此在powershell中跑的时候,
要注意加入各个变量。
from sys import argv
script, input_file = argv # 这里导入想要几个参数
def print_all(f):
print(f.read()) # 不要忘记缩进
def rewind(f):
f.seek(0)
def print_a_line(line_count, f):
print(line_count, f.readline())
current_file = open(input_file)
print("First let's print the whole file:\n")
print_all(current_file)
print("Now let's rewind, kind of like a tape.")
rewind(current_file)
print("Let's print three lines:")
current_line = 1
print_a_line(current_line, current_file)
current_line = current_line + 1
print_a_line(current_line, current_file)
current_line = current_line + 1
print_a_line(current_line, current_file)
> python .\ex20.py .\test.txt
First let's print the whole file:
11
22
33
Now let's rewind, kind of like a tape.
Let's print three lines:
1 11
2 22
3 33
如何理解?
First let's print the whole file:
11
22
33
这是目标文档test.txt
的全部三行。
在ex20.py
中,
我们定义好
script, input_file = argv # 这里导入想要几个参数
当我们要操作$ python
时,
script
代表了ex20.py
,
input_file
代表了我们想被执行文档名称test.txt
。
继续,
.seek(0)
使得文档从第一行开始录入。
每次.readline()
一次,类似于于光标下移到下一个\n
之时。
下面的代码框表示,每次数字加1,表示代码框下移1次,然后print出来这一行是个啥。
current_line = current_line + 1
print_a_line(current_line, current_file)
Exercise 21. Functions Can Return Something
def add(a, b):
print(f"ADDING {a} + {b}")
return a + b
def subtract(a, b):
print(f"SUBTRACTING {a} - {b}")
return a - b
def multiply(a, b):
print(f"MULTIPLYING {a} * {b}")
return a * b
def divide(a, b):
print(f"DIVIDING {a} / {b}")
return a / b
print("Let's do some math with just functions!")
age = add(30, 5)
height = subtract(78, 4)
weight = multiply(90, 2)
iq = divide(100, 2)
print(f"Age: {age}, Height: {height}, Weight: {weight}, IQ: {iq}")
# A puzzle for the extra credit, type it in anyway.
print("Here is a puzzle.")
就是在def中加入了return
这个东西,没什么新的。
> python .\ex21.py
Let's do some math with just functions!
ADDING 30 + 5
SUBTRACTING 78 - 4
MULTIPLYING 90 * 2
DIVIDING 100 / 2
Age: 35, Height: 74, Weight: 180, IQ: 50.0
Here is a puzzle.
Exercise 23. Strings, Bytes, and Character Encodings
这一节好复杂,算了。我还是好好看看我的Python代码吧。
PS C:\Users\lijiaxiang\Downloads\me\trans\myfolder> python .\ex23.py utf-8 strict
b'Afrikaans' <===> Afrikaans
b'\xe9\x87\x86\xe7\x8a\xaa\xe5\x9e\xb1\xe9\x87\x84\xee\x85\x9a\xe5\xa7\x8f' <===> 釆犪垱釄姏
b'\xe8\xa2\x97\xe5\x92\xac\xe8\xa4\x8b\xe8\xa4\x95\xe8\xa8\x96\xe9\x82\xaa' <===> 袗咬褋褕訖邪
b'\xe4\xb8\x95\xe8\xb3\xb1\xe6\xaf\x93\xe4\xb9\x87\xe4\xba\x98\xe8\xb3\xb7\xe4\xb8\x9e' <===> 丕賱毓乇亘賷丞
b'Aragon\xe8\x8c\x85s' <===> Aragon茅s
b'Arpetan' <===> Arpetan
b'Az\xe8\x93\xb9rbaycanca' <===> Az蓹rbaycanca
We call these 1s and 0s “bits.” At the small end a computer will use 8 of these 1s and 0s to encode 256 numbers (0-255).
00000000
would be 0,11111111
would be 255 Today we call a “byte” a sequence of 8 bits (1s and 0s). but now we just say it’s 8 bits.
The most popular convention ended up being American Standard Code for Information Interchange or ASCII. This standard maps a number to a letter. The number 90 is Z, which in bits is 1011010, which gets mapped to the ASCII table inside the computer.
所以 ASCII 是这样来的。
print(0b1011010)
# 90
print(ord('Z'))
# 90
print(chr(90))
# Z
这就是字母的编码。
The problem with ASCII is that it only encodes English and maybe a few other similar languages. Remember that a byte can hold 256 numbers (0-255, or 00000000-11111111). Turns out, there’s a lot more characters than 256 used throughout the world’s languages.
这也说明了为什么ASCII为什么不适用于中文了。
p.109
需要用到的软件和书在这。
Notepad++
Powershell
- Learn Python The Hard Way Chi 2012
- Learn Python The Hard Way Eng 2017