Python程序设计(第三版)课后题答案 第五章
编程练习题
- 1.字符串格式化可以用来简化示例程序。用字符串格式化方法重写该程序。
答案:原本给出的示例程序如下:
def main():
# get the day month and year as numbers
day = int(input("Enter the day number: "))
month = int(input("Enter the month number: "))
year = int(input("Enter the year: "))
date1 = str(month)+"/"+str(day)+"/"+str(year)
months = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"]
monthStr = months[month-1]
date2 = monthStr+" " + str(day) + ", " + str(year)
print("The date is", date1, "or", date2+".")
main()
用字符串格式化方法重新如下:
def main():
# get the day month and year as numbers
day = int(input("Enter the day number: "))
month = int(input("Enter the month number: "))
year = int(input("Enter the year: "))
date1 = str(month) + "/" + str(day) + "/" + str(year)
months = ["January", "February", "March", "April",
"May", "June", "July", "August",
"September", "October", "November", "December"]
monthStr = months[month - 1]
date2 = monthStr + " " + str(day) + ", " + str(year)
# print("The date is", date1, "or", date2+".")
print("The date is {0} or {1}.".format(date1, date2)) # 输出语句字符串格式化
main()
运行结果输出如下:
Enter the day number: 4
Enter the month number: 3
Enter the year: 2021
The date is 3/4/2021 or March 4, 2021.
进程已结束,退出代码0
- 2.某个CS教授给出了5分测验,等级为5-A、4-B、3-C、2-D、1-F、0-F。编写一个程序,接受测验分数作为输入,并打印出相应的等级。
答案:
def main(): # 测验成绩等级转换
grade = int(input("Enter you grade number(0~5): "))
levelist = ['F', 'F', 'D', 'C', 'B', 'A']
print("测验成绩等级为:", levelist[grade])
main()
输出结果如下:
Enter you grade number(0~5): 1
测验成绩等级为: F
进程已结束,退出代码0
- 3.某个CS教授给出100的考试,分数等级为90-100:A、80-89:B、70-79:C、60-69:D、<60、F。编写一个程序,接受考试分数作为输入,并打印出相应的等级。
答案:解题思路:根据分数段划分成绩等级,利用分数做模10运算,得到的值代表分数处于那个分数段,构建分数段对应等级的列表,输出即可。注意的是小于60分数段有多个,需要在列表中重复设置,再者考虑100和大于90都为A级的情况,在列表中设置两个A等级。程序如下:
def main(): # 测验100分制成绩等级转换
grade = int(input("Enter you grade number(0~100): "))
m = grade // 10
levelist = ['F', 'F', 'F', 'F', 'F', 'F', 'D', 'C', 'B', 'A', 'A']
print("测验成绩等级为:", levelist[m])
main()
验证输出如下:
Enter you grade number(0~100): 0
测验成绩等级为: F
Enter you grade number(0~100): 100
测验成绩等级为: A
Enter you grade number(0~100): 84
测验成绩等级为: B
- 4.首字母缩略词是一个单词,是从短语中的单词取第一个字母形成的。例如,RAM是“random access memory”的缩写。编写一个程序,允许用户键入一个短语,然后输出该短语的首字母缩略语。注意:首字母缩略词应该全部为大写,即使短语中的单词没有大写。
答案:
def main(): # 提取短语首字母
phrase = input("Enter a phrase: ")
acronym = '' # 定义缩略语为空
for word in phrase.split():
acronym = acronym + word[0] # 取分割后单词的首字母连接成新的字符串
print("The abbreviation of the phrase is:", acronym.upper()) # 将构造的字符串全部大写
main()
输出如下:
Enter a phrase: random access memory
The abbreviation of the phrase is: RAM
进程已结束,退出代码0
- 5.数学命理学家声称能够基于名字的“数值”来确定一个人的性格特征。名字的值的确定方法是名字中字母的值之和,其中“a”为1、“b”为2、“c”为3,直到“z”为26。例如,名字“Zelle”具有的值为26+5+12+12+5=60(顺便说一下,这恰好是一个非常吉利的数字)。编写一个程序,计算输入的单个名字的数值。
答案:
def main(): # 计算输入的单个名字的数值
name = input("Enter your name: ")
num = 0 # 定义初始数值为0
for ch in name.lower(): # 对全部小写的字符串遍历
num = num + ord(ch) - 96 # ord函数取ASCII数值,该值比题目要求大96,减去
print("名字的数值是:", num)
main()
输出结果:
Enter your name: Zelle
名字的数值是: 60
进程已结束,退出代码0
- 6.扩展前一个问题的解决方案,允许计算完整的名字,如“John Marvin Zelle”或“John Jacob Jingleheimer Smith”。总值就是所有名字的数值之和。
答案:
def main(): # 计算输入的完整名字的数值
name = input("Enter your name: ")
namelink = name.replace(' ', '') # 去掉单词之间的空格
num = 0 # 定义初始数值为0
for ch in namelink.lower(): # 对全部小写的字符串遍历
num = num + ord(ch) - 96 # ord函数取ASCII数值,该值比题目要求大96,减去
print("名字的数值是:", num)
main()
输出结果如下:
Enter your name: John Marvin Zelle
名字的数值是: 184
进程已结束,退出代码0
Enter your name: John Jacob Jingleheimer Smith
名字的数值是: 262
进程已结束,退出代码0
- 7.凯撒密码是一种简单的替换密码,其思路是将明文消息的每个字母在字母表中移动固定数字(称为密钥)。例如,如果键值为2,则单词“Sourpuss”将被编码为“Uqwtrwuu”。原始消息可以通过使用密钥的负值“重新编码”来恢复。编写一个可以编码和解码凯撒密码的程序。对程序的输入将是明文的字符串和密钥的值。输出将是一个编码消息,其中原始消息中的每个字符都将被替代为Unicode字符集中后移秘钥个字符。例如,如果ch是字符串中的字符,key是要移位的量,则替换ch的字符可以计算为chr(ord(ch)+key)。
答案:
def main(): # 编解码凯撒密码的程序
Inmessage = input("Enter the message to be encoded: ")
key = int(input("Enter the key: ")) # 编码时取2,解码时取-2
Outmessage = ''
for ch in Inmessage:
Outmessage = Outmessage + chr(ord(ch) + key)
print("输出编码信息为:", Outmessage)
main()
编码结果如下:
Enter the message to be encoded: Sourpuss
Enter the key: 2
输出编码信息为: Uqwtrwuu
进程已结束,退出代码0
解码结果如下:
Enter the message to be encoded: Uqwtrwuu
Enter the key: -2
输出编码信息为: Sourpuss
进程已结束,退出代码0
- 8.上一个练习有一个问题,它不处理“超出字符表末端”的情况。真正的凯撒密码以循环方式移动,其中“z”之后的下一个字符是“a”。修改上一个问题的解决方案,让它循环。你可以假定输入只包含字母和空格。(提示:创建一个包含字母表所有字符的字符串,并使用此字符串中的位置作为代码。你不必将“z”转换为“a”,只需确保在字母表字符串中对整个字符串序列中使用循环移位。)
答案:
def main(): # 编解码凯撒密码(循环移位)
Inmessage = input("Enter the message to be encoded: ")
key = int(input("Enter the key: ")) # 编码时取2,解码时取-2
library = ' abcdefghigklmnopqrstuvwxyzabABCDEFGHIJKLMNOPQRSTUVWXYZAB' # 构建字符串序列,重点为zab和ZAB以及首位为三个空格
Outmessage = ''
for ch in Inmessage:
Outmessage = Outmessage + library[library.find(ch) + key] # 找到ch在序列中出现的第一个位置,加上位移长度key就是加密后的字符
print("输出编码信息为:", Outmessage)
main()
输出结果如下:
Enter the message to be encoded: abc zab ABC ZAB Sourpuss
Enter the key: 2
输出编码信息为: cde bcd CDE BCD Uqwtrwuu
进程已结束,退出代码0
- 9.编写一个程序,计算用户输入的句子中的单词数。
答案:
def main(): # 计算句子中的单词数
message = input("Enter a sentence: ")
print("句子中单词个数为:", len(message.split(' '))) # 通过空格将句子进行拆分形成单词列表,计算列表长度即为单词个数
main()
输出结果如下:
Enter a sentence: For example, if every 15 students get 8, then
句子中单词个数为: 9
进程已结束,退出代码0
- 10.编写一个程序,计算用户输入句子中的平均单词长度。
答案:
def main(): # 计算句子中的平均单词长度
message = input("Enter a sentence: ")
num = len(message.split(' ')) # 得到句子中单词个数
count = 0
for ch in message:
if (97 <= ord(ch) <= 122) or (65 <= ord(ch) <= 90): # 判断大小写字母字符
count = count + 1 # 计算字母个数
print("单词个数:", num) #
print("字母总长度:", count) #
print("句子中单词平均长度为:", round((count / num), 1)) # 计算平均单词长度,保留1位小数
main()
输出结果如下:
Enter a sentence: I have an apple and I have a pen
单词个数: 9
字母总长度: 24
句子中单词平均长度为: 2.7
进程已结束,退出代码0
- 11.编写第一章中chao.py程序的改进版本,允许用户输入两个初始值和迭代次数,然后打印一个格式很好的表格,显示这些随时间的变化情况。例如,如果初始值为0.25和0.26(10次迭代),表格可能如下所示:
index | 0.25 | 0.26 |
---|---|---|
1 | 0.731250 | 0.750360 |
2 | 0.766441 | 0.730547 |
3 | 0.698135 | 0.767707 |
4 | 0.821896 | 0.695499 |
5 | 0.570894 | 0.825942 |
6 | 0.955399 | 0.560671 |
7 | 0.166187 | 0.960644 |
8 | 0.540418 | 0.147447 |
9 | 0.968629 | 0.490255 |
10 | 0.118509 | 0.974630 |
答案:
def main():
print("This program illustrates a chaotic function")
n = eval(input("How many numbers should I print?:"))
x1 = eval(input("Enter a number between 0 and 1: x1 = "))
x2 = eval(input("Enter a number between 0 and 1: x2 = "))
print("index ", "x1=", x1, " x2=", x2)
print("----------------------------")
for i in range(n):
x1 = 3.9 * x1 - 3.9 * x1 * x1
x2 = 3.9 * x2 - 3.9 * x2 * x2
a = round(x1, 6) # 四舍五入保留6位小数
b = round(x2, 6)
print(" ", i + 1, " ", (str(a) + '0')[0:8], " ", (str(b) + '0')[0:8]) # 将计算值转换为字符串,不足六位小数的补0
# 后保留六位小数;即截取八个字符串长度
main()
输出结果如下:
This program illustrates a chaotic function
How many numbers should I print?:10
Enter a number between 0 and 1: x1 = 0.25
Enter a number between 0 and 1: x2 = 0.26
index x1= 0.25 x2= 0.26
----------------------------
1 0.731250 0.750360
2 0.766441 0.730547
3 0.698135 0.767707
4 0.821896 0.695499
5 0.570894 0.825942
6 0.955399 0.560671
7 0.166187 0.960644
8 0.540418 0.147447
9 0.968629 0.490255
10 0.118509 0.974630
进程已结束,退出代码0
- 12.编写第二章中的futval.py程序的改进版本。程序将提示用户投资金额、年化利率和投资年数。然后程序将输出一个格式正确的表,以年为单位跟踪投资的价值。输出可能如下所示:
Year | Value |
---|---|
0 | $2000.00 |
1 | $2200.00 |
2 | $2420.00 |
3 | $2662.00 |
4 | $2928.20 |
5 | $3221.02 |
6 | $3542.12 |
7 | $3897.43 |
答案:
def main(): # 输入投资金额、年化利率和投资年数,计算输出跟踪投资的价值表格
print("This program calculates the future value of any year investment.")
year = eval(input("Enter the number of years: "))
principal = float(input("Enter the initial principal: "))
apr = 0.1
print("Year ", " Value")
print("----------------")
for i in range(year+1):
value = round(principal, 2)
print(' ', i, ' ', ('$'+str(value)+'0')[0:8])
principal = principal * (1 + apr)
main()
输出结果如下:
This program calculates the future value of any year investment.
Enter the number of years: 7
Enter the initial principal: 2000
Year Value
----------------
0 $2000.00
1 $2200.00
2 $2420.00
3 $2662.00
4 $2928.20
5 $3221.02
6 $3543.12
7 $3897.43
进程已结束,退出代码0
- 13.重做所有以前的编程问题,让它们采用批处理(使用文本文件进行输入和输出)。
答案:
def main(): # 使用文本文件输入和输出,计算跟踪投资价值表格
infile = open("infile.txt", "r")
outfile = open("outfile.txt", "w")
year, value, apr = infile.read().split() # 将输出文件的数值取出赋给参量
print('year value ', file=outfile)
print('-----------------', file=outfile)
for i in range(int(year)+1):
content = ' '+str(i)+' ${0:0.2f}'.format(float(value)) # 字符格式化输出
print(content, file=outfile)
value = float(value) * (1 + float(apr))
# close both files
infile.close()
outfile.close()
print("Usernames have been written to", outfile)
main()
输入文件的内容:
输出文件的内容:
运行窗口输出的内容:
Usernames have been written to <_io.TextIOWrapper name='outfile.txt' mode='w' encoding='cp936'>
进程已结束,退出代码0
- 14.单词计数。UNIX/Linux系统上有一个通用实用程序,名为“wc”。该程序分析一个文件以确定其中包含的行数、单词数和字符数。编写你自己的wc版本。程序接受文件名作为输入,然后打印三个数字,显示文件的行数、单词数和字符数。
答案:
def main(): # 使用文本文件输入,计算文件中的行数,单词数,字符数
infile = open("infile.txt", "r")
linenum = len(infile.readlines()) # 读取行列表,求长度
infile = open("infile.txt", "r")
wordnum = len(infile.read().split()) # 读取全部内容,而后划分单个单词,求长度
infile = open("infile.txt", "r")
chrnum = 0
for ch in infile.read():
if (97 <= ord(ch) <= 122) or (65 <= ord(ch) <= 90): # 判断大小写字母字符
chrnum = chrnum + 1
print('文件的行数为:', linenum)
print('文件的单词数为:', wordnum)
print('文件的字符数为:', chrnum)
main()
输出文件内容为:
输出结果为:
文件的行数为: 3
文件的单词数为: 15
文件的字符数为: 50
进程已结束,退出代码0
- 15.编写一个程序来绘制学生考试成绩的水平柱状图。你的程序应该从文件获取输入。文件的第一行包含文件中学生数量的计数,后续每行包含学生的姓氏,后跟一个0~100范围内的分数。你的程序应为每个学生绘制一个水平柱形,其中柱形的长度表示学生的分数。柱形应该对齐左边缘排列。(提示:使用学生的人数来确定窗口的大小及其坐标。加分需求:在柱形图左边标注学生姓名。)
答案:
def main(): # 使用文件输入学生成绩,绘制水平柱状图
infile = open("infile.txt", "r")
numberstu = infile.readline() # 读取文件第一行的学生人数
numstu = int(numberstu)
win = GraphWin("成绩图", 800, 600)
win.setCoords(0.0, 0.0, 135.0, 32.0 * numstu) # 将图像坐标根据学生人数进行统一
win.setBackground("white")
kywidth = 32.0 * numstu - 5 # 在图中留出5个单位的上边距
zhuwidth = kywidth / (1.5 * (numstu + 1)) # 根据学生人数确定每个柱形的宽度,学生人数+1可以使得图像窗口留有一定的下边距
for i in range(numstu):
s = infile.readline().split() # 读取文件中每一行的学生姓名和成绩,并进行切片操作
sname = s[0] # 切片后数列的第一项为学生姓名
sgrade = int(s[1]) # 切片后数列的第二项为学生成绩,转换为整数格式
t = Text(Point(15, kywidth - (i + 1) * 1.5 * zhuwidth), sname) # 建立文本框,填充学生姓名
t.setFill("black")
t.setSize(13)
t.setStyle("bold")
t.draw(win)
g = Rectangle(Point(30, kywidth - (i + 1) * 1.5 * zhuwidth - 0.5 * zhuwidth), # 建立矩形,长度表示学生成绩
Point(30 + sgrade, kywidth - (i + 1) * 1.5 * zhuwidth + 0.5 * zhuwidth))
g.setFill("gray")
g.draw(win)
win.getMouse()
win.close()
main()
输入文件内容如下:
输出图像如下:
更多学生成绩时,输出文件内容如下:
输出图像如下:
- 16.编写一个程序来绘制测验分数直方图。程序应从文件读取数据。该文件的每一行包含一个在0~10范围内的数字。程序必须计算每个分数出现的次数,然后为每个可能分数(0 ~10)绘制具有柱形垂直柱形图,其高度对应于该分数。例如,如果每15个学生得到8,那么8的柱的高度应该是15。(提示:使用一个列表来存储每个可能得分的计数。)直方图的示例如下。
答案:
def main(): # 使用文件输入分数,绘制直方图
infile = open("infile.txt", "r")
gradelist = infile.readlines() # 读取所有分数,构成列表
win = GraphWin("分数直方图", 800, 600)
win.setCoords(0.0, 0.0, 240, 120)
win.setBackground("white")
for i in range(11):
t = Text(Point(20 + (i * 20), 5), i) # 绘制0-10的直方图横坐标
t.setFill("black")
t.setSize(15)
t.setStyle("bold")
t.draw(win)
for i in range(10):
gradenum = gradelist.count(str(i) + '\n') # 对分数列表的内容循环计数
if gradenum != 0:
g = Rectangle(Point(15 + (i * 20), 10), Point(25 + (i * 20), 10 + gradenum * 10))
g.setFill("gray")
g.draw(win)
win.getMouse()
win.close()
main()
输入文件的内容如下:
输出直方图如下:
如有错误,请读者留言指正!