1-2输入错误:打开你刚创建的文件hello_world.py,在代码中添加一个输入错误,再运行这个程序。输入错误会引发错误吗?你能理解显示的错误消息吗?你能添加一个不会导致错误的输入错误吗?你凭什么认为它不会导致错误?
在Python中使用变量时,需要遵守一些规则和指南。违反这些规则将引发错误,而指南旨在让你编写的代码更容易阅读和理解。请务必牢记下述有关变量的规则。
变量名只能包含字母、数字和下划线。变量名可以字母或下划线打头,但不能以数字打头,例如,可将变量命名为message_1,但不能将其命名为1_message。
变量名不能包含空格,但可使用下划线来分隔其中的单词。例如,变量名greeting_message可行,但变量名greetingmessage会引发错误。
不要将Python关键字和函数名用作变量名,即不要使用Python保留用于特殊用途的单词,如print(请参见附录A.4)。
变量名应既简短又具有描述性。例如,name比n好,student_name比s_n好,name_length比length_of_persons_name好。
动手试一试
请完成下面的练习,在做每个练习时,都编写一个独立的程序。保存每个程序时,使用符合标准Python约定的文件名:使用小写字母和下划线,如simple_message.py和simple_messages.py。
2-1简单消息:将一条消息存储到变量中,再将其打印出来。
message="helloworld!"print(message)===================RESTART:C:/ProgramFiles/Python38/test.py==================helloworld!
2-2多条简单消息:将一条消息存储到变量中,将其打印出来;再将变量的值修改为一条新消息,并将其打印出来。
message="helloworld!"print(message)message="worldhello!"print(message)
==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============helloworld!worldhello!
在Python中,用引号括起的都是字符串,其中的引号可以是单引号,也可以是双引号。
在做下面的每个练习时,都编写一个独立的程序,并将其保存为名称类似于name_cases.py的文件。如果遇到了困难,请休息一会儿或参阅附录C提供的建议。
2-3个性化消息:将用户的姓名存到一个变量中,并向该用户显示一条消息。显示的消息应非常简单,如“HelloEric,wouldyouliketolearnsomePythontoday”。
name="Eric"message="hello!"+name+",wouldyouliketolearnsomePythontoday"print(message)
==========RESTART:C:/ProgramFiles/Python/Python36/message_case.py==========hello!Eric,wouldyouliketolearnsomePythontoday
2-4调整名字的大小写:将一个人名存储到一个变量中,再以小写、大写和首字母大写的方式显示这个人名。
name="smith"print(name.upper())print(name.lower())print(name.title())
==========RESTART:C:/ProgramFiles/Python/Python36/message_case.py==========SMITHsmithSmith
2-5名言:找一句你钦佩的名人说的名言,将这个名人的姓名和他的名言打印出来。输出应类似于下面这样(包括引号):
AlbertEinsteinoncesaid,“Apersonwhonevermadeamistakenevertriedanythingnew.”
print('AlbertEinsteinoncesaid,“Apersonwhonevermadeamistakenevertriedanythingnew.”')
==========RESTART:C:/ProgramFiles/Python/Python36/message_case.py==========AlbertEinsteinoncesaid,“Apersonwhonevermadeamistakenevertriedanythingnew.”
2-6名言2:重复练习2-5,但将名人的姓名存储在变量famous_person中,再创建要显示的消息,并将其存储在变量message中,然后打印这条消息。
famous_person="AlbertEinstein"message=famous_person+'oncesaid,"Apersonwhonevermadeamistakenevertriedanythingnew."'print(message)
==========RESTART:C:/ProgramFiles/Python/Python36/message_case.py==========AlbertEinsteinoncesaid,"Apersonwhonevermadeamistakenevertriedanythingnew."
2-7剔除人名中的空白:存储一个人名,并在其开头和末尾都包含一些空白字符。务必至少使用字符组合"\t"和"\n"各一次。
打印这个人名,以显示其开头和末尾的空白。然后,分别使用剔除函数lstrip()、rstrip()和strip()对人名进行处理,并将结果打印出来。
name="\n\tAlbertEinstein\t\n"print(name)print(name.lstrip())print(name.rstrip())print(name.strip())
==========RESTART:C:/ProgramFiles/Python/Python36/message_case.py==========AlbertEinsteinAlbertEinsteinAlbertEinsteinAlbertEinstein
2-8数字8:编写4个表达式,它们分别使用加法、减法、乘法和除法运算,但结果都是数字8。为使用print语句来显示结果,务必将这些表达式用括号括起来,也就是说,你应该编写4行类似于下面的代码:
print(5+3)输出应为4行,其中每行都只包含数字8。
print(5+3)print(11-3)print(2*4)print(int(24/3))
==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============8888
2-9最喜欢的数字:将你最喜欢的数字存储在一个变量中,再使用这个变量创建一条消息,指出你最喜欢的数字,然后将这条消息打印出来。
number=8print("myfavoritenumberis"+str(number))
==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============myfavoritenumberis8
2-10添加注释:选择你编写的两个程序,在每个程序中都至少添加一条注释。如果程序太简单,实在没有什么需要说明的,就在程序文件开头加上你的姓名和当前日期,再用一句话阐述程序的功能。
2-11Python之禅:在Python终端会话中执行命令importthis,并粗略地浏览一下其他的指导原则。
Beautifulisbetterthanugly.Explicitisbetterthanimplicit.Simpleisbetterthancomplex.Complexisbetterthancomplicated.Flatisbetterthannested.Sparseisbetterthandense.Readabilitycounts.Specialcasesaren'tspecialenoughtobreaktherules.Althoughpracticalitybeatspurity.Errorsshouldneverpasssilently.Unlessexplicitlysilenced.Inthefaceofambiguity,refusethetemptationtoguess.Thereshouldbeone--andpreferablyonlyone--obviouswaytodoit.Althoughthatwaymaynotbeobviousatfirstunlessyou'reDutch.Nowisbetterthannever.Althoughneverisoftenbetterthan*right*now.Iftheimplementationishardtoexplain,it'sabadidea.Iftheimplementationiseasytoexplain,itmaybeagoodidea.Namespacesareonehonkinggreatidea--let'sdomoreofthose!
在本章中,你学习了:如何使用变量;如何创建描述性变量名以及如何消除名称错误和语法错误;字符串是什么,以及如何使用小写、大写和首字母大写方式显示字符串;使用空白来显示整洁的输出,以及如何剔除字符串中多余的空白;如何使用整数和浮点数;使用数值数据时需要注意的意外行为。你还学习了如何编写说明性注释,让代码对你和其他人来说更容易理解。最后,你了解了让代码尽可能简单的理念。
在第3章,你将学习如何在被称为列表的变量中存储信息集,以及如何通过遍历列表来操作其中的信息。
请尝试编写一些简短的程序来完成下面的练习,以获得一些使用Python列表的第一手经验。你可能需要为每章的练习创建一个文件夹,以整洁有序的方式存储为完成各章的练习而编写的程序。
3-1姓名:将一些朋友的姓名存储在一个列表中,并将其命名为names。依次访问该列表中的每个元素,从而将每个朋友的姓名都打印出来。
names=["xiaoming","john","jack","eric"]print(names[0],names[1],names[2],names[3])
==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============xiaomingjohnjackeric
3-2问候语:继续使用练习3-1中的列表,但不打印每个朋友的姓名,而为每人打印一条消息。每条消息都包含相同的问候语,但抬头为相应朋友的姓名。
names=["xiaoming","john","jack","eric"]message="nicetomeetyou!"print(message+names[0])print(message+names[1])print(message+names[2])print(message+names[3])
==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============nicetomeetyou!xiaomingnicetomeetyou!johnnicetomeetyou!jacknicetomeetyou!eric
3-3自己的列表:想想你喜欢的通勤方式,如骑摩托车或开汽车,并创建一个包含多种通勤方式的列表。根据该列表打印一系列有关这些通勤方式的宣言,如“IwouldliketoownaHondamotorcycle”。
1lists=["car","plane","rocket"]2print("Iwouldliketoowna"+lists[0])3print("Iwouldliketoowna"+lists[1])4print("Iwouldliketoowna"+lists[2])==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============IwouldliketoownacarIwouldliketoownaplaneIwouldliketoownarocket
注意方法remove()只删除第一个指定的值。如果要删除的值可能在列表中出现多次,就需要使用循环来判断是否删除了所有这样的值。你将在第7章学习如何这样做。
下面的练习比第2章的练习要复杂些,但让你有机会以前面介绍过的各种方式使用列表。
3-4嘉宾名单:如果你可以邀请任何人一起共进晚餐(无论是在世的还是故去的),你会邀请哪些人?请创建一个列表,其中包含至少3个你想邀请的人;然后,使用这个列表打印消息,邀请这些人来与你共进晚餐。
1names=["马云","马化腾","马斯克"]2print("尊敬的:"+names[0]+","+names[1]+","+names[2]+","+"请来参加我的慈善晚宴!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============尊敬的:马云,马化腾,马斯克,请来参加我的慈善晚宴!
3-5修改嘉宾名单:你刚得知有位嘉宾无法赴约,因此需要另外邀请一位嘉宾。
以完成练习3-4时编写的程序为基础,在程序末尾添加一条print语句,指出哪位嘉宾无法赴约。
修改嘉宾名单,将无法赴约的嘉宾的姓名替换为新邀请的嘉宾的姓名。
再次打印一系列消息,向名单中的每位嘉宾发出邀请。
1names=["马云","马化腾","马斯克"]23name_absent=names.pop(1)4names.insert(1,"马蓉")56print("尊敬的:"+names[0]+","+names[1]+","+names[2]+","+"请来参加我的慈善晚宴!")78print("由于"+name_absent+"帮我打怪练级去了,所以我们又邀请了"+names[1])==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============尊敬的:马云,马克思,马斯克,请来参加我的慈善晚宴!由于马化腾帮我打怪练级去了,所以我们又邀请了马蓉
3-6添加嘉宾:你刚找到了一个更大的餐桌,可容纳更多的嘉宾。请想想你还想邀请哪三位嘉宾。
以完成练习3-4或练习3-5时编写的程序为基础,在程序末尾添加一条print语句,指出你找到了一个更大的餐桌。
使用insert()将一位新嘉宾添加到名单开头。
使用insert()将另一位新嘉宾添加到名单中间。
使用append()将最后一位新嘉宾添加到名单末尾。
打印一系列消息,向名单中的每位嘉宾发出邀请。
1names=["马云","马化腾","马斯克"]23names.insert(0,"马蓉")4names.insert(2,"马东敏")5names.append("马拉多纳")67fornameinnames:8print("尊敬的:"+name+",请来参加我的慈善晚宴!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============尊敬的:马蓉,请来参加我的慈善晚宴!尊敬的:马云,请来参加我的慈善晚宴!尊敬的:马东敏,请来参加我的慈善晚宴!尊敬的:马化腾,请来参加我的慈善晚宴!尊敬的:马斯克,请来参加我的慈善晚宴!尊敬的:马拉多纳,请来参加我的慈善晚宴!
3-7缩减名单:你刚得知新购买的餐桌无法及时送达,因此只能邀请两位嘉宾。
以完成练习3-6时编写的程序为基础,在程序末尾添加一行代码,打印一条你只能邀请两位嘉宾共进晚餐的消息。
使用pop()不断地删除名单中的嘉宾,直到只有两位嘉宾为止。每次从名单中弹出一位嘉宾时,都打印一条消息,让该嘉宾知悉你很抱歉,无法邀请他来共进晚餐。
对于余下的两位嘉宾中的每一位,都打印一条消息,指出他依然在受邀人之列。
使用del将最后两位嘉宾从名单中删除,让名单变成空的。打印该名单,核实程序结束时名单确实是空的
1names=["马云","马化腾","马斯克"]23names.insert(0,"马蓉")4names.insert(2,"马东敏")5names.append("马拉多纳")67print(names.pop()+",很抱歉,位置不够,你不能来参加了!")8print(names.pop()+",很抱歉,位置不够,你不能来参加了!")9print(names.pop()+",很抱歉,位置不够,你不能来参加了!")10print(names.pop()+",很抱歉,位置不够,你不能来参加了!")1112fornameinnames:13print("尊敬的:"+name+",请来参加我的慈善晚宴!")1415delnames[1]16delnames[0]1718print(names)==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============马拉多纳,很抱歉,位置不够,你不能来参加了!马斯克,很抱歉,位置不够,你不能来参加了!马化腾,很抱歉,位置不够,你不能来参加了!马东敏,很抱歉,位置不够,你不能来参加了!尊敬的:马蓉,请来参加我的慈善晚宴!尊敬的:马云,请来参加我的慈善晚宴![]
3-8放眼世界:想出至少5个你渴望去旅游的地方。
将这些地方存储在一个列表中,并确保其中的元素不是按字母顺序排列的。
按原始排列顺序打印该列表。不要考虑输出是否整洁的问题,只管打印原始Python列表。
使用sorted()按字母顺序打印这个列表,同时不要修改它。
再次打印该列表,核实排列顺序未变。
使用sorted()按与字母顺序相反的顺序打印这个列表,同时不要修改它。
使用reverse()修改列表元素的排列顺序。打印该列表,核实排列顺序确实变了。
使用reverse()再次修改列表元素的排列顺序。打印该列表,核实已恢复到原来的排列顺序。
使用sort()修改该列表,使其元素按字母顺序排列。打印该列表,核实排列顺序确实变了。
3-11有意引发错误:如果你还没有在程序中遇到过索引错误,就尝试引发一个这种错误。在你的一个程序中,修改其中的索引,以引发索引错误。关闭程序前,务必消除这个错误。
在本章中,你学习了:列表是什么以及如何使用其中的元素;如何定义列表以及如何增删元素;如何对列表进行永久性排序,以及如何为展示列表而进行临时排序;如何确定列表的长度,以及在使用列表时如何避免索引错误。
在第4章,你将学习如何以更高效的方式处理列表元素。通过使用为数不多的几行代码来遍历列表元素,你就能高效地处理它们,即便列表包含数千乃至数百万个元素。
4-1比萨:想出至少三种你喜欢的比萨,将其名称存储在一个列表中,再使用for循环将每种比萨的名称都打印出来。
修改这个for循环,使其打印包含比萨名称的句子,而不仅仅是比萨的名称。对于每种比萨,都显示一行输出,如“Ilikepepperonipizza”。
在程序末尾添加一行代码,它不在for循环中,指出你有多喜欢比萨。输出应包含针对每种比萨的消息,还有一个总结性句子,如“Ireallylovepizza!”。
1pizzas=["NewOrleans","CheeseLover","DeliciousBacon"]2forpizzainpizzas:3print(pizza)4print("Ilike"+pizza+"pizza")5print("Ireallylovepizza!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============NewOrleansIlikeNewOrleanspizzaCheeseLoverIlikeCheeseLoverpizzaDeliciousBaconIlikeDeliciousBaconpizzaIreallylovepizza!
4-2动物:想出至少三种有共同特征的动物,将这些动物的名称存储在一个列表中,再使用for循环将每种动物的名称都打印出来。
修改这个程序,使其针对每种动物都打印一个句子,如“Adogwouldmakeagreatpet”。
在程序末尾添加一行代码,指出这些动物的共同之处,如打印诸如“Anyoftheseanimalswouldmakeagreatpet!”这样的句子。
1animals=["bird","dog","cat"]23foranimalinanimals:4print("A"+animal+"wouldmakeagreatpet")56print("Anyoftheseanimalswouldmakeagreatpet!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============AbirdwouldmakeagreatpetAdogwouldmakeagreatpetAcatwouldmakeagreatpetAnyoftheseanimalswouldmakeagreatpet!
4-3数到20:使用一个for循环打印数字1~20(含)。
1fornumberinrange(1,21):2print(number,end=',')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,
1numbers=list(range(1,1000001))23fornumberinnumbers:4print(number)
1numbers=list(range(1,1000001))2print(min(numbers))3print(max(numbers))4print(sum(numbers))==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============11000000500000500000
4-6奇数:通过给函数range()指定第三个参数来创建一个列表,其中包含1~20的奇数;再使用一个for循环将这些数字都打印出来。
1numbers=list(range(1,20,2))2fordigitalinnumbers:3print(digital,end=',')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============1,3,5,7,9,11,13,15,17,19,
4-73的倍数:创建一个列表,其中包含3~30内能被3整除的数字;再使用一个for循环将这个列表中的数字都打印出来。
1numbers=list(range(3,31,3))2fordigitalinnumbers:3print(digital,end=',')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============3,6,9,12,15,18,21,24,27,30,
4-8立方:将同一个数字乘三次称为立方。例如,在Python中,2的立方用2**3表示。请创建一个列表,其中包含前10个整数(即1~10)的立方,再使用一个for循环将这些立方数都打印出来。
1numbers=list(range(1,11))2fordigitalinnumbers:3print(digital**3,end=',')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============1,8,27,64,125,216,343,512,729,1000,
4-9立方解析:使用列表解析生成一个列表,其中包含前10个整数的立方。
1a=[digital**3fordigitalinrange(1,11)]2print(a)==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============[1,8,27,64,125,216,343,512,729,1000]
4-10切片:选择你在本章编写的一个程序,在末尾添加几行代码,以完成如下任务。
打印消息“Thefirstthreeitemsinthelistare:”,再使用切片来打印列表的前三个元素。
打印消息“Threeitemsfromthemiddleofthelistare:”,再使用切片来打印列表中间的三个元素。
打印消息“Thelastthreeitemsinthelistare:”,再使用切片来打印列表末尾的三个元素。
1numbers=[1,2,3,4,5,6,7,8,9,10]2print("“Thefirstthreeitemsinthelistare:”")3fornumberinnumbers[:3]:4print(number,end="")56print("\n“Threeitemsfromthemiddleofthelistare:”")7fornumberinnumbers[1:4]:8print(number,end="")910print("\n“Thelastthreeitemsinthelistare:”")11fornumberinnumbers[-3:]:12print(number,end="")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============“Thefirstthreeitemsinthelistare:”123“Threeitemsfromthemiddleofthelistare:”234“Thelastthreeitemsinthelistare:”8910
4-11你的比萨和我的比萨:在你为完成练习4-1而编写的程序中,创建比萨列表的副本,并将其存储到变量friend_pizzas中,再完成如下任务。
在原来的比萨列表中添加一种比萨。
在列表friend_pizzas中添加另一种比萨。
核实你有两个不同的列表。为此,打印消息“Myfavoritepizzasare:”,再使用一个for循环来打印第一个列表;打印消息“Myfriend'sfavoritepizzasare:”,再使用一个for循环来打印第二个列表。核实新增的比萨被添加到了正确的列表中。
1pizzas=["NewOrleans","CheeseLover","DeliciousBacon"]2friend_pizzas=pizzas[:]34pizzas.append("durian")5friend_pizzas.append("BlackPepperBeef")67print("Myfavoritepizzasare:")8forpizzainpizzas:9print(pizza,end=",")1011print("\n\nMyfriend'sfavoritepizzasare:")12forpizzainfriend_pizzas:13print(pizza,end=",")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============Myfavoritepizzasare:NewOrleans,CheeseLover,DeliciousBacon,durian,Myfriend'sfavoritepizzasare:NewOrleans,CheeseLover,DeliciousBacon,BlackPepperBeef,
4-12使用多个循环:在本节中,为节省篇幅,程序foods.py的每个版本都没有使用for循环来打印列表。请选择一个版本的foods.py,在其中编写两个for循环,将各个食品列表都打印出来。
4-13自助餐:有一家自助式餐馆,只提供五种简单的食品。请想出五种简单的食品,并将其存储在一个元组中。
使用一个for循环将该餐馆提供的五种食品都打印出来。
尝试修改其中的一个元素,核实Python确实会拒绝你这样做。
餐馆调整了菜单,替换了它提供的其中两种食品。请编写一个这样的代码块:给元组变量赋值,并使用一个for循环将新元组的每个元素都打印出来。
1pizzas=("NewOrleans","Cheese","Bacon","Beef","durian")2forpizzainpizzas:3print(pizza,end=",")4print("\n")5#pizzas[1]="chicken"67pizzas=("NewOrleans","Cheese","Bacon","chicken","pig")8forpizzainpizzas:9print(pizza,end=",")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============NewOrleans,Cheese,Bacon,Beef,durian,NewOrleans,Cheese,Bacon,chicken,pig,
4-15代码审核:从本章编写的程序中选择三个,根据PEP8指南对它们进行修改。
每级缩进都使用四个空格。对你使用的文本编辑器进行设置,使其在你按Tab键时都插入四个空格;如果你还没有这样做,现在就去做吧(有关如何设置,请参阅附录B)。
每行都不要超过80字符。对你使用的编辑器进行设置,使其在第80个字符处显示一条垂直参考线。
在本章中,你学习了:如何高效地处理列表中的元素;如何使用for循环遍历列表,Python如何根据缩进来确定程序的结构以及如何避免一些常见的缩进错误;如何创建简单的数字列表,以及可对数字列表执行的一些操作;如何通过切片来使用列表的一部分和复制列表。你还学习了元组(它对不应变化的值提供了一定程度的保护),以及在代码变得越来越复杂时如何设置格式,使其易于阅读。
在第5章中,你将学习如何使用if语句在不同的条件下采取不同的措施;学习如何将一组较复杂的条件测试组合起来,并在满足特定条件时采取相应的措施。你还将学习如何在遍历列表时,通过使用if语句对特定元素采取特定的措施。
5-1条件测试:编写一系列条件测试;将每个测试以及你对其结果的预测和实际结果都打印出来。你编写的代码应类似于下面这样:
car='subaru'print("Iscar=='subaru'IpredictTrue.")print(car=='subaru')print("\nIscar=='audi'IpredictFalse.")print(car=='audi')详细研究实际结果,直到你明白了它为何为True或False。创建至少10个测试,且其中结果分别为True和False的测试都至少有5个。
5-2更多的条件测试:你并非只能创建10个测试。如果你想尝试做更多的比较,可再编写一些测试,并将它们加入到conditional_tests.py中。对于下面列出的各种测试,至少编写一个结果为True和False的测试。
检查两个字符串相等和不等。
使用函数lower()的测试。
检查两个数字相等、不等、大于、小于、大于等于和小于等于。
使用关键字and和or的测试。
测试特定的值是否包含在列表中。
测试特定的值是否未包含在列表中。
else是一条包罗万象的语句,只要不满足任何if或elif中的条件测试,其中的代码就会执行,这可能会引入无效甚至恶意的数据。如果知道最终要测试的条件,应考虑使用一个elif代码块来代替else代码块。这样,你就可以肯定,仅当满足相应的条件时,你的代码才会执行。
if-elif-else结构功能强大,但仅适合用于只有一个条件满足的情况:遇到通过了的测试后,Python就跳过余下的测试。这种行为很好,效率很高,让你能够测试一个特定的条件。
然而,有时候必须检查你关心的所有条件。在这种情况下,应使用一系列不包含elif和else代码块的简单if语句。在可能有多个条件为True,且你需要在每个条件为True时都采取相应措施时,适合使用这种方法。
5-3外星人颜色#1:假设在游戏中刚射杀了一个外星人,请创建一个名为alien_color的变量,并将其设置为'green'、'yellow'或'red'。
编写一条if语句,检查外星人是否是绿色的;如果是,就打印一条消息,指出玩家获得了5个点。
编写这个程序的两个版本,在一个版本中上述测试通过了,而在另一个版本中未通过(未通过测试时没有输出)。
1alien_color="green"2ifalien_color=="green":3print("yougot5points")45alien_color="red"6ifalien_color=="green":7print("yougot5points")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============yougot5points
5-4外星人颜色#2:像练习5-3那样设置外星人的颜色,并编写一个if-else结构。
如果外星人是绿色的,就打印一条消息,指出玩家因射杀该外星人获得了5个点。
如果外星人不是绿色的,就打印一条消息,指出玩家获得了10个点。
编写这个程序的两个版本,在一个版本中执行if代码块,而在另一个版本中执行else代码块。
1alien_color="green"2ifalien_color=="green":3print("yougot5points!")4else:5print("yougot10points!")67alien_color="red"8print("\nanothertest:")9ifalien_color=="green":10print("yougot5points")11else:12print("yougot10points!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============yougot5points!anothertest:yougot10points!
5-5外星人颜色#3:将练习5-4中的if-else结构改为if-elif-else结构。
如果外星人是绿色的,就打印一条消息,指出玩家获得了5个点。
如果外星人是黄色的,就打印一条消息,指出玩家获得了10个点。
如果外星人是红色的,就打印一条消息,指出玩家获得了15个点。
编写这个程序的三个版本,它们分别在外星人为绿色、黄色和红色时打印一条消息。
1alien_color="green"2ifalien_color=="green":3print("yougot5points!")4elifalien_color=="yellow":5print("yougot10points!")6elifalien_color=="red":7print("yougot15points!")89alien_color="yellow"10print("\nanothertest:")11ifalien_color=="green":12print("yougot5points!")13elifalien_color=="yellow":14print("yougot10points!")15elifalien_color=="red":16print("yougot15points!")1718alien_color="red"19print("\nanothertest:")20ifalien_color=="green":21print("yougot5points!")22elifalien_color=="yellow":23print("yougot10points!")24elifalien_color=="red":25print("yougot15points!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============yougot5points!anothertest:yougot10points!anothertest:yougot15points!
5-6人生的不同阶段:设置变量age的值,再编写一个if-elif-else结构,根据age的值判断处于人生的哪个阶段。
如果一个人的年龄小于2岁,就打印一条消息,指出他是婴儿。
如果一个人的年龄为2(含)~4岁,就打印一条消息,指出他正蹒跚学步。
如果一个人的年龄为4(含)~13岁,就打印一条消息,指出他是儿童。
如果一个人的年龄为13(含)~20岁,就打印一条消息,指出他是青少年。
如果一个人的年龄为20(含)~65岁,就打印一条消息,指出他是成年人。
如果一个人的年龄超过65(含)岁,就打印一条消息,指出他是老年人。
5-7喜欢的水果:创建一个列表,其中包含你喜欢的水果,再编写一系列独立的if语句,检查列表中是否包含特定的水果。
将该列表命名为favorite_fruits,并在其中包含三种水果。
编写5条if语句,每条都检查某种水果是否包含在列表中,如果包含在列表中,就打印一条消息,如“Youreallylikebananas!”。
1favorite_fruits=["apple","orange","peach"]2if"apple"infavorite_fruits:3print("Youreallylikeapples!")4if"orange"infavorite_fruits:5print("Youreallylikeoranges!")6if"peach"infavorite_fruits:7print("Youreallylikepeachs!")8if"banana"infavorite_fruits:9print("Youreallylikebananas!")10if"pear"infavorite_fruits:11print("Youreallylikepears!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============Youreallylikeapples!Youreallylikeoranges!Youreallylikepeachs!
如果用户名为'admin',就打印一条特殊的问候消息,如“Helloadmin,wouldyouliketoseeastatusreport”。
否则,打印一条普通的问候消息,如“HelloEric,thankyouforlogginginagain”。
1user_list=["john","admin","jack"]23foruserinuser_list:4ifuser=="admin":5print("Hello%s,wouldyouliketoseeastatusreport"%user)6else:7print(f"Hello{user},thankyouforlogginginagain")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============Hellojohn,thankyouforlogginginagainHelloadmin,wouldyouliketoseeastatusreportHellojack,thankyouforlogginginagain
5-9处理没有用户的情形:在为完成练习5-8编写的程序中,添加一条if语句,检查用户名列表是否为空。
如果为空,就打印消息“Weneedtofindsomeusers!”。
删除列表中的所有用户名,确定将打印正确的消息。
1user_list=["john","admin","jack"]23ifuser_list:4foruserinuser_list:5ifuser=="admin":6print("Hello%s,wouldyouliketoseeastatusreport"%user)7else:8print(f"Hello{user},thankyouforlogginginagain")9else:10print("Weneedtofindsomeusers!")111213user_list=[]1415ifuser_list:16foruserinuser_list:17ifuser=="admin":18print("Hello%s,wouldyouliketoseeastatusreport"%user)19else:20print(f"Hello{user},thankyouforlogginginagain")21else:22print("Weneedtofindsomeusers!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============Hellojohn,thankyouforlogginginagainHelloadmin,wouldyouliketoseeastatusreportHellojack,thankyouforlogginginagainWeneedtofindsomeusers!
5-10检查用户名:按下面的说明编写一个程序,模拟网站确保每位用户的用户名都独一无二的方式。
创建一个至少包含5个用户名的列表,并将其命名为current_users。
再创建一个包含5个用户名的列表,将其命名为new_users,并确保其中有一两个用户名也包含在列表current_users中。
遍历列表new_users,对于其中的每个用户名,都检查它是否已被使用。如果是这样,就打印一条消息,指出需要输入别的用户名;否则,打印一条消息,指出这个用户名未被使用。
确保比较时不区分大小写;换句话说,如果用户名'John'已被使用,应拒绝用户名'JOHN'。
1current_users=["john","admin","jack","eric","alice"]2new_users=["smith","Eric","bob","john","michael"]34fornew_userinnew_users:5ifnew_user.lower()incurrent_users:6print(f"{new_user}hasused!")7else:8print(f"{new_user}notused!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============smithnotused!Erichasused!bobnotused!johnhasused!michaelnotused!
5-11序数:序数表示位置,如1st和2nd。大多数序数都以th结尾,只有1、2和3例外。
在一个列表中存储数字1~9。
遍历这个列表。
在循环中使用一个if-elif-else结构,以打印每个数字对应的序数。输出内容应为1st、2nd、3rd、4th、5th、6th、7th、8th和9th,但每个序数都独占一行。
1digitals=list(range(1,10))2fordigitalindigitals:3ifdigital==1:4print("%dst"%digital,end=",")5elifdigital==2:6print(f"{digital}nd",end=",")7elifdigital==3:8print("{}rd".format(digital),end=",")9else:10print(str(digital)+"th",end=",")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============1st,2nd,3rd,4th,5th,6th,7th,8th,9th,
5-12设置if语句的格式:审核你在本章编写的程序,确保正确地设置了条件测试的格式。
5-13自己的想法:与刚拿起本书时相比,现在你是一名能力更强的程序员了。鉴于你对如何在程序中模拟现实情形有了更深入的认识,你可以考虑使用程序来解决一些问题。随着编程技能不断提高,你可能想解决一些问题,请将这方面的想法记录下来。想想你可能想编写的游戏、想研究的数据集以及想创建的Web应用程序。
6-1人:使用一个字典来存储一个熟人的信息,包括名、姓、年龄和居住的城市。该字典应包含键first_name、last_name、age和city。将存储在该字典中的每项信息都打印出来。
1person={2"first_name":"john",3"last_name":"smith",4"age":18,5"city":"beijing"6}7print(person["first_name"],person["last_name"],person["age"],person["city"])==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============johnsmith18beijing
6-2喜欢的数字:使用一个字典来存储一些人喜欢的数字。请想出5个人的名字,并将这些名字用作字典中的键;想出每个人喜欢的一个数字,并将这些数字作为值存储在字典中。打印每个人的名字和喜欢的数字。为让这个程序更有趣,通过询问朋友确保数据是真实的。
6-3词汇表:Python字典可用于模拟现实生活中的字典,但为避免混淆,我们将后者称为词汇表。
想出你在前面学过的5个编程词汇,将它们用作词汇表中的键,并将它们的含义作为值存储在词汇表中。
以整洁的方式打印每个词汇及其含义。为此,你可以先打印词汇,在它后面加上一个冒号,再打印词汇的含义;也可在一行打印词汇,再使用换行符(\n)插入一个空行,然后在下一行以缩进的方式打印词汇的含义。
1dicts={'list':'列表','str':'字符串','tuple':'元组','dict':'字典','int':'整型'}2print('list'+":"+dicts['list'])3print('str'+":"+dicts['str'])4print('tuple'+":"+dicts['tuple'])5print('dict'+":"+dicts['dict'])6print('int'+":"+dicts['int'])==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============list:列表str:字符串tuple:元组dict:字典int:整型
6-4词汇表2:既然你知道了如何遍历字典,现在请整理你为完成练习6-3而编写的代码,将其中的一系列print语句替换为一个遍历字典中的键和值的循环。确定该循环正确无误后,再在词汇表中添加5个Python术语。当你再次运行这个程序时,这些新术语及其含义将自动包含在输出中。
1dicts={'list':'列表','str':'字符串','tuple':'元组','dict':'字典','int':'整型'}2forkey,valueindicts.items():3print(f"{key}:{value}")45dicts['split']='切片'6dicts['if']='条件'7dicts['class']='类'8dicts['object']='对象'9dicts['boolean']='布尔'1011forkey,valueindicts.items():12print(f"{key}:{value}")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============list:列表str:字符串tuple:元组dict:字典int:整型list:列表str:字符串tuple:元组dict:字典int:整型split:切片if:条件class:类object:对象boolean:布尔
6-5河流:创建一个字典,在其中存储三条大河流及其流经的国家。其中一个键—值对可能是'nile':'egypt'。
使用循环为每条河流打印一条消息,如“TheNilerunsthroughEgypt.”。
使用循环将该字典中每条河流的名字都打印出来。
使用循环将该字典包含的每个国家的名字都打印出来。
1dics={'nile':'egypt','longriver':'china','amazon':'brazil'}23forkey,valueindics.items():4print("the%srunsthrough%s"%(key.title(),value.title()))56forvalueinset(dics.values()):7print(value.title())==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============theNilerunsthroughEgypttheLongRiverrunsthroughChinatheAmazonrunsthroughBrazilEgyptBrazilChina
6-6调查:在6.3.1节编写的程序favorite_languages.py中执行以下操作。
创建一个应该会接受调查的人员名单,其中有些人已包含在字典中,而其他人未包含在字典中。
遍历这个人员名单,对于已参与调查的人,打印一条消息表示感谢。对于还未参与调查的人,打印一条消息邀请他参与调查。
1favorite_languages={2'jen':'python',3'sarah':'c',4'edward':'ruby',5'phil':'python',6}78names=['john','jen','phil','alice','eric']910fornameinnames:11ifnameinfavorite_languages.keys():12print('thankyou!%s'%(name.title()))13else:14print('{},please!'.format(name.title()))==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============John,please!thankyou!Jenthankyou!PhilAlice,please!Eric,please!
6-7人:在为完成练习6-1而编写的程序中,再创建两个表示人的字典,然后将这三个字典都存储在一个名为people的列表中。遍历这个列表,将其中每个人的所有信息都打印出来。
1p1={2"first_name":"john",3"last_name":"smith",4"age":18,5"city":"beijing"6}78p2={9"first_name":"jack",10"last_name":"london",11"age":30,12"city":"london"13}1415p3={16"first_name":"michael",17"last_name":"jackson",18"age":65,19"city":"paris"20}212223peoples=[p1,p2,p3]2425forpeopleinpeoples:26forkey,valueinpeople.items():27print(f"{key}:{value}")28print('---------------------')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============first_name:johnlast_name:smithage:18city:beijingfirst_name:jacklast_name:londonage:30city:londonfirst_name:michaellast_name:jacksonage:65city:paris>>>==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============first_name:johnlast_name:smithage:18city:beijing---------------------first_name:jacklast_name:londonage:30city:london---------------------first_name:michaellast_name:jacksonage:65city:paris---------------------
6-8宠物:创建多个字典,对于每个字典,都使用一个宠物的名称来给它命名;在每个字典中,包含宠物的类型及其主人的名字。将这些字典存储在一个名为pets的列表中,再遍历该列表,并将宠物的所有信息都打印出来。
1xiaomao={'type':'cat','master':'xiaoming'}2xiaogou={'type':'dog','master':'xiaohong'}3xiaoji={'type':'chicken','master':'xiaojun'}45pets=[xiaomao,xiaogou,xiaoji]67forpetinpets:8forkey,valueinpet.items():9print("{0}:{1}".format(key,value))10print("--------------------------")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============type:catmaster:xiaoming--------------------------type:dogmaster:xiaohong--------------------------type:chickenmaster:xiaojun--------------------------
6-9喜欢的地方:创建一个名为favorite_places的字典。在这个字典中,将三个人的名字用作键;对于其中的每个人,都存储他喜欢的1~3个地方。为让这个练习更有趣些,可让一些朋友指出他们喜欢的几个地方。遍历这个字典,并将其中每个人的名字及其喜欢的地方打印出来。
1favorite_places={'jack':['beijing','tianjing'],'john':['guangzhou','shenzhen',2'zhuhai'],'alice':['shanghai','suzhou','wuxi']}34forkey,valuesinfavorite_places.items():5print(f"{key}'sfavoritepleacesis:",end='')6forvalueinvalues:7print(value,end=',')8print("\n----------------------------------------------------")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============jack'sfavoritepleacesis:beijing,tianjing,----------------------------------------------------john'sfavoritepleacesis:guangzhou,shenzhen,zhuhai,----------------------------------------------------alice'sfavoritepleacesis:shanghai,suzhou,wuxi,----------------------------------------------------
6-10喜欢的数字:修改为完成练习6-2而编写的程序,让每个人都可以有多个喜欢的数字,然后将每个人的名字及其喜欢的数字打印出来。
6-11城市:创建一个名为cities的字典,其中将三个城市名用作键;对于每座城市,都创建一个字典,并在其中包含该城市所属的国家、人口约数以及一个有关该城市的事实。在表示每座城市的字典中,应包含country、population和fact等键。将每座城市的名字以及有关它们的信息都打印出来。
1cities={2'shanghai':{'country':'china','popultion':'10000'},3'newyork':{'country':'american','popultion':'1000'},4'london':{'country':'english','popultion':'100'}5}67forkey,valueincities.items():8print(key+":")9forkey1,value1invalue.items():10print(f"{key1}:{value1}")11print('--------------------------------')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============shanghai:country:chinapopultion:10000--------------------------------newyork:country:americanpopultion:1000--------------------------------london:country:englishpopultion:100--------------------------------
6-12扩展:本章的示例足够复杂,可以以很多方式进行扩展了。请对本章的一个示例进行扩展:添加键和值、调整程序要解决的问题或改进输出的格式。
在本章中,你学习了:如何定义字典,以及如何使用存储在字典中的信息;如何访问和修改字典中的元素,以及如何遍历字典中的所有信息;如何遍历字典中所有的键-值对、所有的键和所有的值;如何在列表中嵌套字典、在字典中嵌套列表以及在字典中嵌套字典。
在下一章中,你将学习while循环以及如何从用户那里获取输入。这是激动人心的一章,让你知道如何将程序变成交互性的——能够对用户输入作出响应。
7-1汽车租赁:编写一个程序,询问用户要租赁什么样的汽车,并打印一条消息,如“LetmeseeifIcanfindyouaSubaru”。
1car=input("whichcardoyoulike>")2print(f"LetmeseeifIcanfindyoua{car}")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============whichcardoyoulike>bmwLetmeseeifIcanfindyouabmw
7-2餐馆订位:编写一个程序,询问用户有多少人用餐。如果超过8人,就打印一条消息,指出没有空桌;否则指出有空桌。
1number=input('howmanypeople>')2number=int(number)3ifnumber>8:4print("getout!")5else:6print("comein!")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============howmanypeople>8comein>>>==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============howmanypeople>9getout!
7-310的整数倍:让用户输入一个数字,并指出这个数字是否是10的整数倍。
1number=int(input('digital,please:'))2ifnumber%10==0:3print('justit!')4else:5print('NO!')==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============digital,please:10justit!>>>==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============digital,please:3NO!>>>==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============digital,please:33NO!
7-4比萨配料:编写一个循环,提示用户输入一系列的比萨配料,并在用户输入'quit'时结束循环。每当用户输入一种配料后,都打印一条消息,说我们会在比萨中添加这种配料。
1active=True23whileactive:4prompt="\nPleaseenterthetopping:"5prompt+="\n(Enter'quit'whenyouarefinished.)>"6topping=input(prompt)78iftopping=='quit':9active=False10else:11print(f"ok,{topping}willbeadded!")==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============Pleaseenterthetopping:(Enter'quit'whenyouarefinished.)>beefok,beefwillbeadded!Pleaseenterthetopping:(Enter'quit'whenyouarefinished.)>quit
7-5电影票:有家电影院根据观众的年龄收取不同的票价:不到3岁的观众免费;3~12岁的观众为10美元;超过12岁的观众为15美元。请编写一个循环,在其中询问用户的年龄,并指出其票价。
1whileTrue:2prompt="\nPleaseenteryourage:"3prompt+="\n(Enter'quit'whenyouarefinished.)>"4age=input(prompt)56ifage=="quit":7print("bye!")8break9elifint(age)<3:10print("free!")11elifint(age)<=12:12print("10dollars!")13elifint(age)>12:14print("15dollars!")==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============Pleaseenteryourage:(Enter'quit'whenyouarefinished.)>1210dollars!Pleaseenteryourage:(Enter'quit'whenyouarefinished.)>310dollars!Pleaseenteryourage:(Enter'quit'whenyouarefinished.)>2free!Pleaseenteryourage:(Enter'quit'whenyouarefinished.)>quitbye!
7-6三个出口:以另一种方式完成练习7-4或练习7-5,在程序中采取如下所有做法。
在while循环中使用条件测试来结束循环。
使用变量active来控制循环结束的时机。
使用break语句在用户输入'quit'时退出循环。
1topping=""2active=True34prompt="\nPleaseenterthetopping:"5prompt+="\n(Enter'quit'whenyouarefinished.)>"67print("------------------first-------------------")8whiletopping!="quit":9topping=input(prompt)10iftopping!="quit":11print(f"ok,{topping}willbeadded!")1213print("\n------------------second-------------------")14whileactive:15topping=input(prompt)16iftopping=="quit":17active=False18else:19print(f"ok,{topping}willbeadded!")2021print("\n------------------third-------------------")22whileTrue:23topping=input(prompt)24iftopping=="quit":25break26else:27print(f"ok,{topping}willbeadded!")
7-7无限循环:编写一个没完没了的循环,并运行它(要结束该循环,可按Ctrl+C,也可关闭显示输出的窗口)。
7-8熟食店:创建一个名为sandwich_orders的列表,在其中包含各种三明治的名字;再创建一个名为finished_sandwiches的空列表。遍历列表sandwich_orders,对于其中的每种三明治,都打印一条消息,如Imadeyourtunasandwich,并将其移到列表finished_sandwiches。所有三明治都制作好后,打印一条消息,将这些三明治列出来。
7-9五香烟熏牛肉(pastrami)卖完了:使用为完成练习7-8而创建的列表sandwich_orders,并确保'pastrami'在其中至少出现了三次。在程序开头附近添加这样的代码:打印一条消息,指出熟食店的五香烟熏牛肉卖完了;再使用一个while循环将列表sandwich_orders中的'pastrami'都删除。确认最终的列表finished_sandwiches中不包含'pastrami'。
7-10梦想的度假胜地:编写一个程序,调查用户梦想的度假胜地。使用类似于“Ifyoucouldvisitoneplaceintheworld,wherewouldyougo”的提示,并编写一个打印调查结果的代码块。
在本章中,你学习了:如何在程序中使用input()来让用户提供信息;如何处理文本和数字输入,以及如何使用while循环让程序按用户的要求不断地运行;多种控制while循环流程的方式:设置活动标志、使用break语句以及使用continue语句;如何使用while循环在列表之间移动元素,以及如何从列表中删除所有包含特定值的元素;如何结合使用while循环和字典。
在第8章中,你将学习函数。函数让你能够将程序分成多个很小的部分,其中每部分都负责完成一项具体任务。你可以根据需要调用同一个函数任意次,还可将函数存储在独立的文件中。使用函数可让你编写的代码效率更高,更容易维护和排除故障,还可在众多不同的程序中重用。
8-1消息:编写一个名为display_message()的函数,它打印一个句子,指出你在本章学的是什么。调用这个函数,确认显示的消息正确无误。
1defdisplay_message():2print("function!")34display_message()==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============function!
8-2喜欢的图书:编写一个名为favorite_book()的函数,其中包含一个名为title的形参。这个函数打印一条消息,如OneofmyfavoritebooksisAliceinWonderland。调用这个函数,并将一本图书的名称作为实参传递给它。
1deffavorite_book(title):2print(f"Oneofmyfavoritebooksis{title}。")34favorite_book("AliceinWonderland")==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============OneofmyfavoritebooksisAliceinWonderland。
8-3T恤:编写一个名为make_shirt()的函数,它接受一个尺码以及要印到T恤上的字样。这个函数应打印一个句子,概要地说明T恤的尺码和字样。
使用位置实参调用这个函数来制作一件T恤;再使用关键字实参来调用这个函数。
1defmake_shirt(size,message):2print(f"yourshirt'ssizeis{size},andthemessageis{message}")34make_shirt(1,"hello1")5make_shirt(size=2,message="hello2")6make_shirt(message="hello3",size=3)>>>==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============yourshirt'ssizeis1,andthemessageishello1yourshirt'ssizeis2,andthemessageishello2yourshirt'ssizeis3,andthemessageishello3
8-4大号T恤:修改函数make_shirt(),使其在默认情况下制作一件印有字样“IlovePython”的大号T恤。调用这个函数来制作如下T恤:一件印有默认字样的大号T恤、一件印有默认字样的中号T恤和一件印有其他字样的T恤(尺码无关紧要)。
1defmake_shirt(size="big",message="ilovepython"):2print(f"yourshirt'ssizeis{size},andthemessageis{message}")34make_shirt()5make_shirt(size="middle")6make_shirt(message="hello3",size=3)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============yourshirt'ssizeisbig,andthemessageisilovepythonyourshirt'ssizeismiddle,andthemessageisilovepythonyourshirt'ssizeis3,andthemessageishello3
8-5城市:编写一个名为describe_city()的函数,它接受一座城市的名字以及该城市所属的国家。这个函数应打印一个简单的句子,如ReykjavikisinIceland。给用于存储国家的形参指定默认值。为三座不同的城市调用这个函数,且其中至少有一座城市不属于默认国家。
1defdescribe_city(city,country="china"):2print(f"{city}isin{country}")34describe_city("reykjavik","iceland")5describe_city("beijing")6describe_city("shanghai","china")==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============reykjavikisinicelandbeijingisinchinashanghaiisinchina
8-6城市名:编写一个名为city_country()的函数,它接受城市的名称及其所属的国家。这个函数应返回一个格式类似于下面这样的字符串:
"Santiago,Chile"至少使用三个城市-国家对调用这个函数,并打印它返回的值。
1defcity_country(city,country):2message=city+','+country3returnmessage45print(city_country("Santiago","Chile"))6print(city_country("london","england"))7print(city_country("beijing","china")==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============Santiago,Chilelondon,englandbeijing,china
8-7专辑:编写一个名为make_album()的函数,它创建一个描述音乐专辑的字典。这个函数应接受歌手的名字和专辑名,并返回一个包含这两项信息的字典。使用这个函数创建三个表示不同专辑的字典,并打印每个返回的值,以核实字典正确地存储了专辑的信息。
给函数make_album()添加一个可选形参,以便能够存储专辑包含的歌曲数。如果调用这个函数时指定了歌曲数,就将这个值添加到表示专辑的字典中。调用这个函数,并至少在一次调用中指定专辑包含的歌曲数。
1defmake_album(singer,album,number=""):2album={'album_name':album,'singer_name':singer}3ifnumber:4album["number"]=number5returnalbum67album1=make_album("A","aa")8print(album1)910album2=make_album("A","aa",'3')11print(album2)==============RESTART:C:/ProgramFiles/Python/Python36/test.py=============={'album_name':'aa','singer_name':'A'}{'album_name':'aa','singer_name':'A','number':'3'}
8-8用户的专辑:在为完成练习8-7编写的程序中,编写一个while循环,让用户输入一个专辑的歌手和名称。获取这些信息后,使用它们来调用函数make_album(),并将创建的字典打印出来。在这个while循环中,务必要提供退出途径。
1defmake_album(singer,album,number=""):2album={'album_name':album,'singer_name':singer}3ifnumber:4album["number"]=number5returnalbum67whileTrue:8print("\npleaseenterthealbuminformation:")9print("(enter'q'atanytoquit.)")1011album_name=input("albumname:>")12ifalbum_name=='q':13break1415singer_name=input("singername:>")16ifsinger_name=='q':17break1819a=make_album(album_name,singer_name)20print(a)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============pleaseenterthealbuminformation:(enter'q'atanytoquit.)albumname:>absingername:>cd{'album_name':'cd','singer_name':'ab'}pleaseenterthealbuminformation:(enter'q'atanytoquit.)albumname:>q
8-9魔术师:创建一个包含魔术师名字的列表,并将其传递给一个名为show_magicians()的函数,这个函数打印列表中每个魔术师的名字。
1magician_list=['a','b','c']23defshow_magicians(magicians):4formagicianinmagicians:5print(magician)67show_magicians(magician_list)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============abc
8-10了不起的魔术师:在你为完成练习8-9而编写的程序中,编写一个名为make_great()的函数,对魔术师列表进行修改,在每个魔术师的名字中都加入字样“theGreat”。调用函数show_magicians(),确认魔术师列表确实变了。
1magician_list=['a','b','c']23defshow_magicians(magicians):4formagicianinmagicians:5print(magician)678defmake_great(magician_list):9foriinrange(0,len(magician_list)):10magician_list[i]="theGreat"+magician_list[i]111213make_great(magician_list)1415show_magicians(magician_list)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============theGreatatheGreatbtheGreatc
另一种实现,用到了刚学到的知识:
1magician_list=['a','b','c']2magician_new=[]34defshow_magicians(magicians):5formagicianinmagicians:6print(magician)78defmake_great(magician_list):9whilemagician_list:10current="thegreat"+magician_list.pop()11magician_new.append(current)1213make_great(magician_list)1415show_magicians(magician_new)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============thegreatcthegreatbthegreata
8-11不变的魔术师:修改你为完成练习8-10而编写的程序,在调用函数make_great()时,向它传递魔术师列表的副本。由于不想修改原始列表,请返回修改后的列表,并将其存储到另一个列表中。分别使用这两个列表来调用show_magicians(),确认一个列表包含的是原来的魔术师名字,而另一个列表包含的是添加了字样“theGreat”的魔术师名字。
1magician_list=['a','b','c']2magician_new=[]34defshow_magicians(magicians):5formagicianinmagicians:6print(magician)78defmake_great(magician_list):9whilemagician_list:10current="thegreat"+magician_list.pop()11magician_new.append(current)1213make_great(magician_list[:])1415show_magicians(magician_new)16show_magicians(magician_list)==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============thegreatcthegreatbthegreataabc
8-12三明治:编写一个函数,它接受顾客要在三明治中添加的一系列食材。这个函数只有一个形参(它收集函数调用中提供的所有食材),并打印一条消息,对顾客点的三明治进行概述。调用这个函数三次,每次都提供不同数量的实参。
1deffood_message(*foods):2forfoodinfoods:3print(food)45food_message("a")6print("------------------")7food_message('a',"b")8print("------------------")9food_message("a",'b','c')==============RESTART:C:/ProgramFiles/Python/Python36/test.py==============a------------------ab------------------abc
8-13用户简介:复制前面的程序user_profile.py,在其中调用build_profile()来创建有关你的简介;调用这个函数时,指定你的名和姓,以及三个描述你的键-值对。
1defbuild_profile(first,last,**user_info):2"""创建一个字典,其中包含我们知道的有关用户的一切"""3profile={}4profile['first_name']=first5profile['last_name']=last6forkey,valueinuser_info.items():7profile[key]=value8returnprofile910user_profile=build_profile('albert','einstein',11location='princeton',12field='physics',13age=18)1415print(user_profile)==============RESTART:C:/ProgramFiles/Python/Python36/test.py=============={'first_name':'albert','last_name':'einstein','location':'princeton','field':'physics','age':18}
8-14汽车:编写一个函数,将一辆汽车的信息存储在一个字典中。这个函数总是接受制造商和型号,还接受任意数量的关键字实参。这样调用这个函数:提供必不可少的信息,以及两个名称—值对,如颜色和选装配件。这个函数必须能够像下面这样进行调用:
car=make_car('subaru','outback',color='blue',tow_package=True)打印返回的字典,确认正确地处理了所有的信息。
1defcars(manufacturer,car_type,**items):2car_info={}3car_info['manufacturer']=manufacturer4car_info['car_type']=car_type5forkey,valueinitems.items():6car_info[key]=value7returncar_info89car_info=cars('BMW',740,color='red',displacement='5.2L',number=4)1011print(car_info)==============RESTART:C:/ProgramFiles/Python/Python36/test.py=============={'manufacturer':'BMW','car_type':740,'color':'red','displacement':'5.2L','number':4}
8-15打印模型:将示例print_models.py中的函数放在另一个名为printing_functions.py的文件中;在print_models.py的开头编写一条import语句,并修改这个文件以使用导入的函数。
printing_functions.py
1defprint_models(unprinted_designs,completed_models):2whileunprinted_designs:3current_design=unprinted_designs.pop()45#模拟根据设计制作3D打印模型的过程6print("Printingmodel:"+current_design)7completed_models.append(current_design)89defshow_completed_models(completed_models):10"""显示打印好的所有模型"""11print("\nThefollowingmodelshavebeenprinted:")12forcompleted_modelincompleted_models:13print(completed_model)print_models.py
1importprinting_functions23#首先创建一个列表,其中包含一些要打印的设计4unprinted_designs=['iphonecase','robotpendant','dodecahedron']5completed_models=[]67printing_functions.print_models(unprinted_designs,completed_models)89printing_functions.show_completed_models(completed_models)==========RESTART:C:\ProgramFiles\Python\Python36\print_models.py==========Printingmodel:dodecahedronPrintingmodel:robotpendantPrintingmodel:iphonecaseThefollowingmodelshavebeenprinted:dodecahedronrobotpendantiphonecase
8-16导入:选择一个你编写的且只包含一个函数的程序,并将这个函数放在另一个文件中。在主程序文件中,使用下述各种方法导入这个函数,再调用它:
importmodule_namefrommodule_nameimportfunction_namefrommodule_nameimportfunction_nameasfnimportmodule_nameasmnfrommodule_nameimport*8-17函数编写指南:选择你在本章中编写的三个程序,确保它们遵循了本节介绍的函数编写指南。
在本章中,你学习了:如何编写函数,以及如何传递实参,让函数能够访问完成其工作所需的信息;如何使用位置实参和关键字实参,以及如何接受任意数量的实参;显示输出的函数和返回值的函数;如何将函数同列表、字典、if语句和while循环结合起来使用。你还知道了如何将函数存储在被称为模块的独立文件中,让程序文件更简单、更易于理解。最后,你学习了函数编写指南,遵循这些指南可让程序始终结构良好,并对你和其他人来说易于阅读。
程序员的目标之一是,编写简单的代码来完成任务,而函数有助于你实现这样的目标。它们让你编写好代码块并确定其能够正确运行后,就可置之不理。确定函数能够正确地完成其工作后,你就可以接着投身于下一个编码任务。
函数让你编写代码一次后,想重用它们多少次就重用多少次。需要运行函数中的代码时,只需编写一行函数调用代码,就可让函数完成其工作。需要修改函数的行为时,只需修改一个代码块,而所做的修改将影响调用这个函数的每个地方。
使用函数让程序更容易阅读,而良好的函数名概述了程序各个部分的作用。相对于阅读一系列的代码块,阅读一系列函数调用让你能够更快地明白程序的作用。
函数还让代码更容易测试和调试。如果程序使用一系列的函数来完成其任务,而其中的每个函数都完成一项具体的工作,测试和维护起来将容易得多:你可编写分别调用每个函数的程序,并测试每个函数是否在它可能遇到的各种情形下都能正确地运行。经过这样的测试后你就能信心满满,深信你每次调用这些函数时,它们都将正确地运行。
在第9章,你将学习编写类。类将函数和数据整洁地封装起来,让你能够灵活而高效地使用它们。
9-1餐馆:创建一个名为Restaurant的类,其方法__init__()设置两个属性:restaurant_name和cuisine_type。创建一个名为describe_restaurant()的方法和一个名为open_restaurant()的方法,其中前者打印前述两项信息,而后者打印一条消息,指出餐馆正在营业。
根据这个类创建一个名为restaurant的实例,分别打印其两个属性,再调用前述两个方法。
1classRestaurant():23def__init__(self,restaurant_name,cuisine_type):4self.restaurant_name=restaurant_name5self.cuisine_type=cuisine_type67defdescribe_restaurant(self):8print(f"restaurantnameis{self.restaurant_name}")9print(f"cuisinetypeis{self.cuisine_type}")1011defopen_restaurant(self):12print("Open")1314restaurant=Restaurant("chuancai","hotpot")1516restaurant.describe_restaurant()17restaurant.open_restaurant()==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============restaurantnameischuancaicuisinetypeishotpotOpen
9-2三家餐馆:根据你为完成练习9-1而编写的类创建三个实例,并对每个实例调用方法describe_restaurant()。
9-3用户:创建一个名为User的类,其中包含属性first_name和last_name,还有用户简介通常会存储的其他几个属性。在类User中定义一个名为describe_user()的方法,它打印用户信息摘要;再定义一个名为greet_user()的方法,它向用户发出个性化的问候。
创建多个表示不同用户的实例,并对每个实例都调用上述两个方法。
1classUser():2def__init__(self,first_name,last_name):3self.first_name=first_name4self.last_name=last_name56defdescribe_user(self):7print(f"usernameis:"+self.first_name+""+self.last_name)89defgreet_user(self):10print("hello,{}!".format(self.last_name))1112user_1=User("John","Smith")13user_1.describe_user()14user_1.greet_user()1516user_2=User("xiao","ming")17user_2.describe_user()18user_2.greet_user()==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============usernameis:JohnSmithhello,Smith!usernameis:xiaominghello,ming!
9-4就餐人数:在为完成练习9-1而编写的程序中,添加一个名为number_served的属性,并将其默认值设置为0。根据这个类创建一个名为restaurant的实例;打印有多少人在这家餐馆就餐过,然后修改这个值并再次打印它。
添加一个名为set_number_served()的方法,它让你能够设置就餐人数。调用这个方法并向它传递一个值,然后再次打印这个值。
添加一个名为increment_number_served()的方法,它让你能够将就餐人数递增。调用这个方法并向它传递一个这样的值:你认为这家餐馆每天可能接待的就餐人数。
1classRestaurant():23def__init__(self,restaurant_name,cuisine_type):4self.restaurant_name=restaurant_name5self.cuisine_type=cuisine_type6self.number_served=078defdescribe_restaurant(self):9print(f"restaurantnameis{self.restaurant_name}")10print(f"cuisinetypeis{self.cuisine_type}")1112defopen_restaurant(self):13print("Open")1415defset_number_served(self,number):16self.number_served=number17print(f"{self.number_served}personhasserved!")1819defincrement_number_served(self,numbers):20self.number_served+=numbers21print(f"{self.number_served}personhasserved!")2223restaurant=Restaurant("chuancai","hotpot")24restaurant.set_number_served(10)25restaurant.increment_number_served(20)26restaurant.increment_number_served(30)==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============10personhasserved!30personhasserved!60personhasserved!
根据User类创建一个实例,再调用方法increment_login_attempts()多次。打印属性login_attempts的值,确认它被正确地递增;然后,调用方法reset_login_attempts(),并再次打印属性login_attempts的值,确认它被重置为0。
1classUser():2def__init__(self,first_name,last_name):3self.first_name=first_name4self.last_name=last_name5self.login_attempts=067defincrement_login_attempts(self):8self.login_attempts+=1910defreset_login_attempts(self):11self.login_attempts=01213user_1=User("John","Smith")14user_1.increment_login_attempts()15user_1.increment_login_attempts()16user_1.increment_login_attempts()17print(user_1.login_attempts)1819user_1.reset_login_attempts()20print(user_1.login_attempts)0==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============30
9-6冰淇淋小店:冰淇淋小店是一种特殊的餐馆。编写一个名为IceCreamStand的类,让它继承你为完成练习9-1或练习9-4而编写的Restaurant类。这两个版本的Restaurant类都可以,挑选你更喜欢的那个即可。添加一个名为flavors的属性,用于存储一个由各种口味的冰淇淋组成的列表。编写一个显示这些冰淇淋的方法。创建一个IceCreamStand实例,并调用这个方法。
1classRestaurant():23def__init__(self,restaurant_name,cuisine_type):4self.restaurant_name=restaurant_name5self.cuisine_type=cuisine_type67defdescribe_restaurant(self):8print(f"restaurantnameis{self.restaurant_name}")9print(f"cuisinetypeis{self.cuisine_type}")1011defopen_restaurant(self):12print("Open")1314classIceCreamStand(Restaurant):15def__init__(self,restaurant_name,cuisine_type):16super().__init__(restaurant_name,cuisine_type)17self.flavors=[]1819defshow_icecream(self):20forflavorinself.flavors:21print(flavor)2223icecream=IceCreamStand("haagen-Dazs","icecream")24icecream.flavors=["a","b","c"]2526icecream.show_icecream()==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============abc
9-7管理员:管理员是一种特殊的用户。编写一个名为Admin的类,让它继承你为完成练习9-3或练习9-5而编写的User类。添加一个名为privileges的属性,用于存储一个由字符串(如"canaddpost"、"candeletepost"、"canbanuser"等)组成的列表。编写一个名为show_privileges()的方法,它显示管理员的权限。创建一个Admin实例,并调用这个方法。
1classUser():2def__init__(self,first_name,last_name):3self.first_name=first_name4self.last_name=last_name56defdescribe_user(self):7print(f"usernameis:"+self.first_name+""+self.last_name)89defgreet_user(self):10print("hello,{}!".format(self.last_name))1112classAdmin(User):13def__init__(self,first_name,last_name):14super().__init__(first_name,last_name)15self.privileges=["canaddpost","candeletepost","canbanuser"]1617defshow_privileges(self):18forprivilegeinself.privileges:19print(privilege)2021admin=Admin("John","Smith")2223admin.show_privileges()==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============canaddpostcandeletepostcanbanuser
9-8权限:编写一个名为Privileges的类,它只有一个属性——privileges,其中存储了练习9-7所说的字符串列表。将方法show_privileges()移到这个类中。在Admin类中,将一个Privileges实例用作其属性。创建一个Admin实例,并使用方法show_privileges()来显示其权限。
1classUser():2def__init__(self,first_name,last_name):3self.first_name=first_name4self.last_name=last_name56defdescribe_user(self):7print(f"usernameis:"+self.first_name+""+self.last_name)89defgreet_user(self):10print("hello,{}!".format(self.last_name))111213classPrivileges():14def__init__(self):15self.privileges=["canaddpost","candeletepost","canbanuser"]1617defshow_privileges(self):18forprivilegeinself.privileges:19print(privilege)2021classAdmin(User):22def__init__(self,first_name,last_name):23super().__init__(first_name,last_name)24self.privilege=Privileges()2526defshow_privileges(self):27self.privilege.show_privileges()2829admin=Admin("John","Smith")3031admin.show_privileges()==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============canaddpostcandeletepostcanbanuser
9-9电瓶升级:在本节最后一个electric_car.py版本中,给Battery类添加一个名为upgrade_battery()的方法。这个方法检查电瓶容量,如果它不是85,就将它设置为85。创建一辆电瓶容量为默认值的电动汽车,调用方法get_range(),然后对电瓶进行升级,并再次调用get_range()。你会看到这辆汽车的续航里程增加了。
9-10导入Restaurant类:将最新的Restaurant类存储在一个模块中。在另一个文件中,导入Restaurant类,创建一个Restaurant实例,并调用Restaurant的一个方法,以确认import语句正确无误。
9-11导入Admin类:以为完成练习9-8而做的工作为基础,将User、Privileges和Admin类存储在一个模块中,再创建一个文件,在其中创建一个Admin实例并对其调用方法show_privileges(),以确认一切都能正确地运行。
9-12多个模块:将User类存储在一个模块中,并将Privileges和Admin类存储在另一个模块中。再创建一个文件,在其中创建一个Admin实例,并对其调用方法show_privileges(),以确认一切都依然能够正确地运行。
9-13使用OrderedDict:在练习6-4中,你使用了一个标准字典来表示词汇表。请使用OrderedDict类来重写这个程序,并确认输出的顺序与你在字典中添加键—值对的顺序一致。
1fromcollectionsimportOrderedDict23dicts={'list':'列表','str':'字符串','tuple':'元组','dict':'字典','int':'整型'}45dicts['split']='切片'6dicts['if']='条件'7dicts['class']='类'8dicts['object']='对象'9dicts['boolean']='布尔'1011order_dicts=OrderedDict()12forkey,valueindicts.items():13order_dicts[key]=value1415forkey,valueinorder_dicts.items():16print(f"{key}:{value}")==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============list:列表str:字符串tuple:元组dict:字典int:整型split:切片if:条件class:类object:对象boolean:布尔
9-14骰子:模块random包含以各种方式生成随机数的函数,其中的randint()返回一个位于指定范围内的整数,例如,下面的代码返回一个1~6内的整数:
fromrandomimportrandintx=randint(1,6)请创建一个Die类,它包含一个名为sides的属性,该属性的默认值为6。编写一个名为roll_die()的方法,它打印位于1和骰子面数之间的随机数。创建一个6面的骰子,再掷10次。创建一个10面的骰子和一个20面的骰子,并将它们都掷10次。
1fromrandomimportrandint23classDie():4def__init__(self,sides=6):5self.sides=sides67defroll_die(self):8x=randint(1,self.sides)9print(x,end="")1011print("\n-----------6------------")12dice_6=Die()1314i=015whilei<10:16dice_6.roll_die()17i=i+11819print("\n-----------10------------")20dice_10=Die(10)2122i=023whilei<10:24dice_6.roll_die()25i=i+12627dice_10=Die(10)2829print("\n-----------20------------")30dice_6=Die(20)31i=032whilei<10:33dice_6.roll_die()34i=i+1==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============-----------6------------4411226353-----------10------------5443264212-----------20------------883132017541611
类名应采用驼峰命名法,即将类名中的每个单词的首字母都大写,而不使用下划线。实例名和模块名都采用小写格式,并在单词之间加上下划线。
对于每个类,都应紧跟在类定义后面包含一个文档字符串。这种文档字符串简要地描述类的功能,并遵循编写函数的文档字符串时采用的格式约定。每个模块也都应包含一个文档字符串,对其中的类可用于做什么进行描述。
可使用空行来组织代码,但不要滥用。在类中,可使用一个空行来分隔方法;而在模块中,可使用两个空行来分隔类。
需要同时导入标准库中的模块和你编写的模块时,先编写导入标准库模块的import语句,再添加一个空行,然后编写导入你自己编写的模块的import语句。在包含多条import语句的程序中,这种做法让人更容易明白程序使用的各个模块都来自何方。
你了解到,通过将类存储在模块中,并在需要使用这些类的文件中导入它们,可让项目组织有序。你学习了Python标准库,并见识了一个使用模块collections中的OrderedDict类的示例。最后,你学习了编写类时应遵循的Python约定。
在第10章中,你将学习如何使用文件,这让你能够保存你在程序中所做的工作,以及你让用户做的工作。你还将学习异常,这是一种特殊的Python类,用于帮助你在发生错误时采取相应的措施。
10-1Python学习笔记:在文本编辑器中新建一个文件,写几句话来总结一下你至此学到的Python知识,其中每一行都以“InPythonyoucan”打头。将这个文件命名为learning_python.txt,并将其存储到为完成本章练习而编写的程序所在的目录中。编写一个程序,它读取这个文件,并将你所写的内容打印三次:第一次打印时读取整个文件;第二次打印时遍历文件对象;第三次打印时将各行存储在一个列表中,再在with代码块外打印它们。
1print("\n----------------1-----------------")2withopen("learning_python.txt")asfbj:3content=fbj.read().rstrip()4print(content)56print("\n----------------2-----------------")7withopen("learning_python.txt")asfbj:8forlineinfbj:9print(line.rstrip())1011print("\n----------------3-----------------")12withopen("learning_python.txt")asfbj:13lines=fbj.readlines()1415forlineinlines:16print(line.rstrip())==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============----------------1-----------------InPythonyoucansingInPythonyoucancryInPythonyoucandance----------------2-----------------InPythonyoucansingInPythonyoucancryInPythonyoucandance----------------3-----------------InPythonyoucansingInPythonyoucancryInPythonyoucandance
10-2C语言学习笔记:可使用方法replace()将字符串中的特定单词都替换为另一个单词。下面是一个简单的示例,演示了如何将句子中的'dog'替换为'cat':
>>>message="Ireallylikedogs.">>>message.replace('dog','cat')'Ireallylikecats.'读取你刚创建的文件learning_python.txt中的每一行,将其中的Python都替换为另一门语言的名称,如C。将修改后的各行都打印到屏幕上。
1withopen("learning_python.txt")asfbj:2lines=fbj.readlines()34forlineinlines:5re_line=line.replace("Python","c")6print(re_line)==============RESTART:C:\ProgramFiles\Python\Python36\test.py==============IncyoucansingIncyoucancryIncyoucandance
10-3访客:编写一个程序,提示用户输入其名字;用户作出响应后,将其名字写入到文件guest.txt中。
1withopen("guest.txt",'w')asfbj:2txt=input("enteryourusername:>")3fbj.write(txt)
10-4访客名单:编写一个while循环,提示用户输入其名字。用户输入其名字后,在屏幕上打印一句问候语,并将一条访问记录添加到文件guest_book.txt中。确保这个文件中的每条记录都独占一行。
1whileTrue:2prompt="pleaseenteryourname:"3prompt+="\n(enter'q'whenyouquit)>"4text=input(prompt)5iftext=='q':6break7greet="welcome:"+text+"!\n"8print(greet)9withopen("guest_book.txt","a")asfbj:10fbj.write(greet)
10-5关于编程的调查:编写一个while循环,询问用户为何喜欢编程。每当用户输入一个原因后,都将其添加到一个存储所有原因的文件中。
1whileTrue:2prompt="why!"3prompt+="\n(enter'q'whenyouquit)>"4text=input(prompt)5iftext=='q':6break7withopen("guest_book.txt","a")asfbj:8fbj.write(text+"\n")
10-6加法运算:提示用户提供数值输入时,常出现的一个问题是,用户提供的是文本而不是数字。在这种情况下,当你尝试将输入转换为整数时,将引发TypeError异常。编写一个程序,提示用户输入两个数字,再将它们相加并打印结果。在用户输入的任何一个值不是数字时都捕获TypeError异常,并打印一条友好的错误消息。对你编写的程序进行测试:先输入两个数字,再输入一些文本而不是数字。
1try:2number_1=int(input("firstnumber:>"))3number_2=int(input("secondnumber:>"))4exceptValueError:5print("pleaseenterthenumber")6else:7print(number_1+number_2)
10-7加法计算器:将你为完成练习10-6而编写的代码放在一个while循环中,让用户犯错(输入的是文本而不是数字)后能够继续输入数字。
1whileTrue:2try:3number_1=int(input("firstnumber:>"))4number_2=int(input("secondnumber:>"))5exceptValueError:6print("pleaseenteranumber!")7else:8print(number_1+number_2)9break
10-8猫和狗:创建两个文件cats.txt和dogs.txt,在第一个文件中至少存储三只猫的名字,在第二个文件中至少存储三条狗的名字。编写一个程序,尝试读取这些文件,并将其内容打印到屏幕上。将这些代码放在一个try-except代码块中,以便在文件不存在时捕获FileNotFound错误,并打印一条友好的消息。将其中一个文件移到另一个地方,并确认except代码块中的代码将正确地执行。
1try:2withopen("cat.txt")asfbj_1:3print(fbj_1.read())4withopen("dog.txt")asfbj_2:5print(fbj_2.read())6exceptFileNotFoundError:7print("filenotfound!")
10-9沉默的猫和狗:修改你在练习10-8中编写的except代码块,让程序在文件不存在时一言不发。
1try:2withopen("cat.txt")asfbj_1:3print(fbj_1.read())4withopen("dog.txt")asfbj_2:5print(fbj_2.read())6exceptFileNotFoundError:7pass
你可以使用方法count()来确定特定的单词或短语在字符串中出现了多少次。例如,下面的代码计算'row'在一个字符串中出现了多少次:
>>>line="Row,row,rowyourboat">>>line.count('row')7+/*2>>>line.lower().count('row')3请注意,通过使用lower()将字符串转换为小写,可捕捉要查找的单词出现的所有次数,而不管其大小写格式如何。
编写一个程序,它读取你在项目Gutenberg中获取的文件,并计算单词'the'在每个文件中分别出现了多少次。
1withopen("test.txt")asfbj:2contents=fbj.read()3numbers=contents.lower().count("the")4print(numbers)
10-11喜欢的数字:编写一个程序,提示用户输入他喜欢的数字,并使用json.dump()将这个数字存储到文件中。再编写一个程序,从文件中读取这个值,并打印消息“Iknowyourfavoritenumber!It's_____.”。
1importjson23filename="number.json"4withopen(filename,'w')asfbj:5number=input("enteryoufavoritenumber:>")6json.dump(number,fbj)7withopen(filename,'r')asfbj:8number=json.load(fbj)9print("Iknowyourfavoritenumber!It's"+number)
10-12记住喜欢的数字:将练习10-11中的两个程序合而为一。如果存储了用户喜欢的数字,就向用户显示它,否则提示用户输入他喜欢的数字并将其存储到文件中。运行这个程序两次,看看它是否像预期的那样工作。
1importjson23filename="number.json"45try:6withopen(filename)asfbj:7number=json.load(fbj)8exceptFileNotFoundError:9number=input("enteryoufavoritenumber:>")10print("yourfavoritenumberis:"+number)11withopen(filename,'w')asfbj:12json.dump(number,fbj)13else:14print("Iknowyourfavoritenumber!It's"+number)
10-13验证用户:最后一个remember_me.py版本假设用户要么已输入其用户名,要么是首次运行该程序。我们应修改这个程序,以应对这样的情形:当前和最后一次运行该程序的用户并非同一个人。
为此,在greet_user()中打印欢迎用户回来的消息前,先询问他用户名是否是对的。如果不对,就调用get_new_username()让用户输入正确的用户名。
1importjson23defget_stored_username():4"""Getstoredusernameifavailable."""5filename='username.json'6try:7withopen(filename)asf_obj:8username=json.load(f_obj)9exceptFileNotFoundError:10returnNone11else:12returnusername1314defget_new_username():15"""Promptforanewusername."""16username=input("Whatisyourname")17filename='username.json'18withopen(filename,'w')asf_obj:19json.dump(username,f_obj)20returnusername2122defgreet_user():23"""Greettheuserbyname."""24username=get_stored_username()25ifusername:26flag=input(f"yournameis{username},yesorno>")27ifflag=="yes":28print("Welcomeback,"+username+"!")29elifflag=="no":30username=get_new_username()31print("We'llrememberyouwhenyoucomeback,"+username+"!")32else:33print("inputerror!")34else:35username=get_new_username()36print("We'llrememberyouwhenyoucomeback,"+username+"!")3738greet_user()
在本章中,你学习了:如何使用文件;如何一次性读取整个文件,以及如何以每次一行的方式读取文件的内容;如何写入文件,以及如何将文本附加到文件末尾;什么是异常以及如何处理程序可能引发的异常;如何存储Python数据结构,以保存用户提供的信息,避免用户每次运行程序时都需要重新提供。
在第11章中,你将学习高效的代码测试方式,这可帮助你确定代码正确无误,以及发现扩展现有程序时可能引入的bug。
11-1城市和国家:编写一个函数,它接受两个形参:一个城市名和一个国家名。这个函数返回一个格式为City,Country的字符串,如Santiago,Chile。将这个函数存储在一个名为city_functions.py的模块中。
创建一个名为test_cities.py的程序,对刚编写的函数进行测试(别忘了,你需要导入模块unittest以及要测试的函数)。编写一个名为test_city_country()的方法,核实使用类似于'santiago'和'chile'这样的值来调用前述函数时,得到的字符串是正确的。运行test_cities.py,确认测试test_city_country()通过了。
1importunittest23defcountry_city(city,country):4return(city+","+country).title()56classCityTestCases(unittest.TestCase):7deftest_city_country(self):8self.assertEqual(country_city("Santiago","Chile"),"Santiago,Chile")910unittest.main()
11-2人口数量:修改前面的函数,使其包含第三个必不可少的形参population,并返回一个格式为City,Country-populationxxx的字符串,如Santiago,Chile-population5000000。运行test_cities.py,确认测试test_city_country()未通过。
修改上述函数,将形参population设置为可选的。再次运行test_cities.py,确认测试test_city_country()又通过了。
再编写一个名为test_city_country_population()的测试,核实可以使用类似于'santiago'、'chile'和'population=5000000'这样的值来调用这个函数。再次运行test_cities.py,确认测试test_city_country_population()通过了。
1importunittest23defcountry_city(city,country,population=""):4ifpopulation:5info=city.title()+","+country.title()+"-population"+str(population)6else:7info=city.title()+","+country.title()8return(info)910classCityTestCases(unittest.TestCase):11deftest_city_country(self):12self.assertEqual(country_city("Santiago","Chile"),"Santiago,Chile")1314deftest_city_country_population(self):15self.assertEqual(country_city("Santiago","Chile",10000),"Santiago,Chile-population10000")1617unittest.main()
11-3雇员:编写一个名为Employee的类,其方法__init__()接受名、姓和年薪,并将它们都存储在属性中。编写一个名为give_raise()的方法,它默认将年薪增加5000美元,但也能够接受其他的年薪增加量。
为Employee编写一个测试用例,其中包含两个测试方法:test_give_default_raise()和test_give_custom_raise()。使用方法setUp(),以免在每个测试方法中都创建新的雇员实例。运行这个测试用例,确认两个测试都通过了。
1importunittest23classEmployee():4def__init__(self,first,last,money):5self.first=first6self.last=last7self.money=money89defgive_raise(self,increase=50):10self.money+=increase11returnself.money1213classEmployeeTestCase(unittest.TestCase):14defsetUp(self):15self.employee=Employee("john","smith",1000)1617deftest_give_default_raise(self):18self.employee.give_raise()19self.assertEqual(self.employee.money,1050)2021deftest_give_custom_raise(self):22self.employee.give_raise(100)23self.assertEqual(self.employee.money,1100)2425unittest.main()
在本章中,你学习了:如何使用模块unittest中的工具来为函数和类编写测试;如何编写继承unittest.TestCase的类,以及如何编写测试方法,以核实函数和类的行为符合预期;如何使用方法setUp()来根据类高效地创建实例并设置其属性,以便在类的所有测试方法中都可使用它们。
测试是很多初学者都不熟悉的主题。作为初学者,并非必须为你尝试的所有项目编写测试;但参与工作量较大的项目时,你应对自己编写的函数和类的重要行为进行测试。这样你就能够更加确定自己所做的工作不会破坏项目的其他部分,你就能够随心所欲地改进既有代码了。如果不小心破坏了原来的功能,你马上就会知道,从而能够轻松地修复问题。相比于等到不满意的用户报告bug后再采取措施,在测试未通过时采取措施要容易得多。
如果你在项目中包含了初步测试,其他程序员将更敬佩你,他们将能够更得心应手地尝试使用你编写的代码,也更愿意与你合作开发项目。如果你要跟其他程序员开发的项目共享代码,就必须证明你编写的代码通过了既有测试,通常还需要为你添加的新行为编写测试。
请通过多开展测试来熟悉代码测试过程。对于自己编写的函数和类,请编写针对其重要行为的测试,但在项目早期,不要试图去编写全覆盖的测试用例,除非有充分的理由这样做。