目录
第11章(代码过多不在此处进行书写,需要的可以自行下载)
http://链接:https://pan.baidu.com/s/1bqg62id6zn8UF8gGiGYSGg?pwd=gnub 提取码:gnub
本文档仅供参考,更新了8/9/10章
第2章
2.4.1打印购物小票
蚂蚁森林是支付宝客户端发起“碳账户”的一款公益活动:用户通过步行、地铁出行、在线消费等行为,可在蚂蚁森林中获取能量,当能量到达一定数值后,用户可以在支付宝中申请一颗虚拟的树,申请成功后会收到支付宝发放的一张植树证书。植树证书中包含申请日期、树苗编号等信息,具体如图2-1所示。
图2-1
import datetime
i = datetime.datetime.now()
opp1 = int(input('金士顿U盘8GB购买的数量:'))
opp2 = int(input('胜创16GBTF卡购买的数量:'))
opp3 = int(input('读卡器购买的数量:'))
opp4 = int(input('网线2米购买的数量:'))
print('.'*35)
print('单号:DH201409230001')
print('时间:%s'%i)
print('='*35)
a1=40
a2=50
a3=8
a4=5
sum1=opp1+opp2+opp3+opp4
money1=opp1*a1
money2=opp2*a2
money3=opp3*a3
money4=opp4*a4
sum2=money1+money2+money3+money4
print('名称 数量 单价 金额')
print('金士顿U盘8GB %s %.2f %.2f'%(opp1,a1,money1))
print('胜创16GBTF卡 %s %.2f %.2f'%(opp2,a2,money2))
print('读卡器 %s %.2f %.2f'%(opp3,a3,money3))
print('网线2米 %s %.2f %.2f'%(opp4,a4,money4))
print('='*35)
print('总数:%s'%sum1+' 金额:%.2f'%sum2)
print('折后总额:%.2f'%sum2)
print('实收:%.2f'%sum2+' 找零:0.00')
print('收银:管理员')
print('.'*35)
运行结果:
2.4.2 打印蚂蚁森林植树证书
蚂蚁森林是支付宝客户端发起“碳账户”的一款公益活动:用户通过步行、地铁出行、在线消费等行为,可在蚂蚁森林中获取能量,当能量到达一定数值后,用户可以在支付宝中申请一颗虚拟的树,申请成功后会收到支付宝发放的一张植树证书。植树证书中包含申请日期、树苗编号等信息,具体如图2-2所示。
图2-2
import time
import datetime
year = datetime.datetime.now().year
month = datetime.datetime.now().month
day = datetime.datetime.now().day
x = input('请输入你想要种植的数:')
print(' 植树证书1 \n')
print(' 谢谢你 \n')
print(f'你于{year}年{month}月{day}日申请种植的%s,\n已被中国扶贫基金会认领,将种植到\n威武地区。'%(x))
print('\n\n 树苗编号 ')
print(' NO.HFK20308960305')
运行结果:
2.7.1绝对温标
绝对温标又称开氏温标、热力学温标,是热力学和统计物理中的重要参数之一,也是国际单位制七个基本物理量之一。绝对温标的单位为开尔文(简称开,符号为K),绝对温标的零度对应我们日常使用的摄氏温度(单位为摄氏度,简称度,符号为℃)的-273.15℃。本实例要求编写代码,实现将用户输入的摄氏温度转换为以绝对温标标识的开氏温度的功能。
celsius = float(input("请输入摄氏温度:"))
kelvin = celsius + 273.15
print(celsius,"℃对应的开尔文为:",kelvin)
运行结果:
2.7.2身体质量指数
BMI指数即身体健康指数,它与人的体重和身高相关,是目前国际常用的衡量人体胖瘦程度以及是否健康的一个标准。已知BMI值的计算公式如下:
体质指数(BMI)= 体重(kg)÷身高^2(m)
本实例要求编写代码实现根据用户输入的身高体重计算BMI指数的功能。
height = float(input('请输入您的身高(m):'))
weight = float(input('请输入您的体重(kg):'))
BMI = weight / (height ** 2)
print('您的BMI值为:',BMI)
运行结果:
课后编程题1:编写程序,要求程序能根据用户输入的圆的半径数据计算圆的面积(圆的面积公式:S=πr2),并分别输出圆的直径和面积。
r = float(input('请输入圆的半径:'))
d = 2 * r
area = 3.14 * (r**2)
print('圆的直径为:',d)
print('圆的面积为:',area)
运行结果:
课后编程题2:已知某煤场有29.5t煤,先用一辆载重4t的汽车运3次,剩下的用一辆载重为2.5t的汽车运输,请计算还需要运送几次才能送完?编写程序,解答此问题。
sum = 29.5
a = sum-4*3
b = int(a/2.5)
print('还需要运算的次数为:',b)
运行结果:
第3章
3.2.1 计算器
计算器极大地提高了人们进行数字计算的效率与准确性,无论是超市的收银台,还是集市的小摊位,都能够看到计算器的身影。计算器最基本的功能是四则运算。本实例要求编写代码,实现计算器的四则运算功能。
a = float(input('请输入第一个数:'))
b = float(input('请输入第二个数:'))
c = input('请选择运算符:+ - * /:')
if c=='+':
print(a+b)
elif c=='-':
print(a-b)
elif c=='*':
print(a*b)
elif c=='/':
if b==0:
print('除数不能为0')
else:
print(a/b)
运行结果:
3.2.2 猜数字
猜数游戏是一个古老的密码破译类、益智类小游戏,通常由两个人参与,一个人设置一个数字,一个人猜数字,当猜数字的人说出一个数字,由出数字的人告知是否猜中:若猜测的数字大于设置的数字,出数字的人提示“很遗憾,你猜大了”;若猜测的数字小于设置的数字时,出数字的人提示“很遗憾,你猜小了”;若猜数字的人在规定的次数内猜中设置的数字,出数字的人提示“恭喜,猜数成功”。
本实例要求编写程序,实现上述规则的猜数字游戏,并限制猜数机会只有5次。
num = input('请设定一个数字:')
for degree in range(1,6):
number = input(f'请输入第{degree}次猜测的数字:')
if int(number)<0 or int(number)>100:
print('请输入1-100范围的数字')
elif int(num) == int(number):
print('恭喜猜数成功')
break
elif int(num) > int(number):
print('很遗憾,你猜小了')
else:
print('很遗憾,你猜大了')
if degree == 5:
print('很遗憾,猜数机会用完了')
运行结果:
3.4.1 逢7拍手游戏
逢7拍手游戏的规则是:从1开始顺序数数,数到有7或者包含7的倍数的时候拍手。本实例要求编写程序,模拟实现逢七拍手游戏,输出100以内需要拍手的数字。
for i in range(1,101):
if "7" in str(i) or int(i)%7==0:
print("拍手",end=' ')
elif "7" not in str(i) or int(i)%7!=0:
print(i,end=' ')
if i%20==0: #每隔20个换行
print('\n')
运行结果:
3.4.2 打印五子棋棋盘
五子棋是一种由双人对弈的纯策略型棋类游戏,它使用的棋盘一般由横纵等距的各15条平行线构成,这些线垂直交叉形成的225个交叉点为对弈双方的落子点。本案例要求编写代码,实现按用户要求打印指定大小的五子棋棋盘的程序(10×10的五子棋棋盘如图3-1所示)。
3-1五子棋棋盘示例
size = int(input('请输入棋盘的大小:'))
for i in range(size):
for j in range(size):
if i==0 and j==0:
print('┌',end='')
elif i==0 and j==size-1:
print('┐',end='')
elif i==size-1 and j==0:
print('└',end='')
elif i==size-1 and j==size-1:
print('┘',end='')
elif j==0:
print('├',end='')
elif i==size-1:
print('┴',end='')
elif j==size-1:
print('┤',end='')
elif i==0:
print('┬',end='')
else:
print('┼',end='')
print('')
运行结果:(因为符合原因,运行出来会有些粗糙,见谅)
3.6 房贷计算器
房贷计算器是支付宝平台中搭载的一款在线计算工具,按用户选择的贷款类型(商业贷款、公积金贷款、组合贷款)、贷款金额(万)、期限(年)、利率(%)可计算得出每月月供参考(元)、支付利息(元)、还款总额(元)这些信息,关于这些信息的计算方式如下:
每月月供参考 = 贷款金额 × [月利率 × (1 + 月利率) ^ 还款月数] ÷ { [(1 +月利率) ^ 还款月数] – 1}
还款总额 = 每月月供参考 × 期限 × 12
支付利息 = 还款总额 – 贷款金额 × 10000
以上计算方式中月利率(月利率=利率÷12)指以月为计息周期计算的利息。不同贷款类型的利率是不同的:对于商业贷款而言,五年以下(含五年)的贷款利率是4.75%,五年以上的贷款利率是4.90%;对于公积金贷款利率而言,五年以下(含五年)的贷款利率是2.75%,五年以上的利率是3.25%。
本案例要求编写程序,根据以上计算方式开发一个房贷计算器。
# 等额本息(均使用基准利率)
# 组合贷可作为课后习题
# 商业贷款利率:4.9%
# 公积金利率:3.25%
# 每月还款额=贷款本金×[月利率×(1+月利率) ^ 还款月数]÷{[(1+月利率) ^ 还款月数]-1}
while True:
loan_type = input("请选择贷款类型:1.商业贷款 2.公积金贷款 3.组合贷款\n")
# 贷款金额
if loan_type != '3':
loan_amount = float(input("请输入贷款金额(万)\n"))
term = int(input("请选择期限(年):5、10、15、20、25\n"))
if term in [5,10,15,20,25]:
if term==5:
mon_rate = (4.75 / 100) / 12 # 计算月利率
# 计算每月应还金额
mon_pay = loan_amount * 10000 * (mon_rate * ((1 + mon_rate) ** (term * 12))) / (
((1 + mon_rate) ** (term * 12)) - 1)
# 计算还款总额
all_pay = mon_pay * term * 12
# 计算支付利息
interest = all_pay - loan_amount * 10000
print("每月月供参考(元):{:.2f}元".format(mon_pay))
print("支付利息(元):{:.2f}元".format(interest))
print("还款总额(元):{:.2f}元".format(all_pay))
else:
# 商业贷款
if loan_type == '1': # 商业贷款
mon_rate = (4.90 / 100) / 12 # 计算月利率
# 计算每月应还金额
mon_pay = loan_amount * 10000 * (mon_rate * ((1 + mon_rate) ** (term * 12))) / (
((1 + mon_rate) ** (term * 12)) - 1)
# 计算还款总额
all_pay = mon_pay * term * 12
# 计算支付利息
interest = all_pay - loan_amount * 10000
print("每月月供参考(元):{:.2f}元".format(mon_pay))
print("支付利息(元):{:.2f}元".format(interest))
print("还款总额(元):{:.2f}元".format(all_pay))
elif loan_type == '2': # 公积金贷款
if term==5:
mon_rate = (2.75 / 100) / 12 # 计算月利率
else:
mon_rate = (3.25 / 100) / 12 # 计算月利率
# 计算每月应还金额
mon_pay = loan_amount * 10000 * (mon_rate * ((1 + mon_rate) ** (term * 12))) / (
((1 + mon_rate) ** (term * 12)) - 1)
# 计算还款总额
all_pay = mon_pay * term * 12
# 计算支付利息
interest = all_pay - loan_amount * 10000
print("每月月供参考(元):{:.2f}元".format(mon_pay))
print("支付利息(元):{:.2f}元".format(interest))
print("还款总额(元):{:.2f}元".format(all_pay))
else:
print('请输入合法的期限')
else:
# 商贷金额
business_loan = float(input("请输入商业贷款金额(万):\n"))
# 公积金贷款
fund_loan = float(input("请输入公积金贷款金额(万):\n"))
term = int(input("请选择期限(年):5、10、15、20、25\n"))
if term in [5, 10, 15, 20, 25]:
if term ==5:
business_mon_rate = (4.75 / 100) / 12 # 商贷月利率
found_mon_rate = (2.75 / 100) / 12 # 公积金月利率
else:
business_mon_rate = (4.90 / 100) / 12 # 商贷月利率
found_mon_rate = (3.25 / 100) / 12 # 公积金月利率
# 计算商业贷款 每月应还金额
business_mon_pay = business_loan * 10000 * (business_mon_rate * ((1 + business_mon_rate) ** (term * 12))) / (
((1 + business_mon_rate) ** (term * 12)) - 1)
# 计算公积金贷款 每月应还金额
found_mon_pay = fund_loan * 10000 * (found_mon_rate * ((1 + found_mon_rate) ** (term * 12))) / (
((1 + found_mon_rate) ** (term * 12)) - 1)
# 每月总应还
mon_all_pay = business_mon_pay + found_mon_pay
all_pay = mon_all_pay * term * 12
# 计算支付利息
interest = all_pay - (business_loan + fund_loan)*10000
print("每月月供参考(元):{:.2f}元".format(mon_all_pay))
print("支付利息(元):{:.2f}元".format(interest))
print("还款总额(元):{:.2f}元".format(all_pay))
else:
print('请输入合法的期限')
运行结果:
课后编程题1:编写程序,实现利用while循环输出100以内偶数的功能。
i = 0
while i<101:
if i%2==0 and i!=0:
print(i,end=' ')
if i % 40 == 0:
print('\n')
i+=1
运行结果:
课后编程题2:编写程序,实现判断用户输入的数是正数还是负数的功能。
i = float(input('请输入一个数:'))
if i==0:
print(f'{i}既不是正数也不是负数')
elif i>0:
print(f'{i}是一个正数')
else:
print(f'{i}是一个负数')
运行结果:
课后编程题2:编写程序,实现输出100以内质数的功能。
for i in range(2,100): #先取100以内的数
for j in range(2,i): #再取小于i取得数
if i%j == 0: #较大的数除以较小的数
break #如果取余为0表示J是i的因子,舍去,结束本次i所在数的所有循环
else:
print(i,end=' ') #无法整除所有j,则无因子
运行结果:
第4章
4.3.1进制转换
十进制是实际应用中最常使用的计数方式,除此之外,还可以采用二进制、八进制或十六进制计数。本实例要求编写代码,实现将用户输入的十进制整数转换为指定进制的功能。
num = int(input('请输入要转换的数据:\n'))
ch = input('请选择转换进制:2、8、10、16\n')
if ch=='2':
print(f'进制转换后的数据为:{bin(num)}')
if ch=='8':
print(f'进制转换后的数据为:{oct(num)}')
if ch=='10':
print(f'进制转换后的数据为:{int(num)}')
if ch=='16':
print(f'进制转换后的数据为:{hex(num)}')
'''
if ch=='2':
print('进制转换后的数据为:{:b}')
if ch=='8':
print(f'进制转换后的数据为:{:o}')
if ch=='10':
print(f'进制转换后的数据为:{:d}')
if ch=='16':
print(f'进制转换后的数据为:{:x}')
'''
运行结果:
4.3.2 文本进度条
进度条一般以图形的方式显示已完成任务量和未完成任务量,并以动态文字的方式显示任务的完成度。
import time
incomplete_sign = 50 # .的数量
print('='*23+'开始下载'+'='*25)
for i in range(incomplete_sign + 1):
completed = "*" * i # 表示已完成
incomplete = "." * (incomplete_sign - i) # 表示未完成
percentage = (i / incomplete_sign) * 100 # 百分比
print("\r{:.0f}%[{}{}]".format(percentage, completed,
incomplete), end="")
time.sleep(0.5)
print("\n" + '='*23+'下载完成'+'='*25)
运行结果:
4.5.1 过滤敏感词
敏感词通常是指带有敏感政治倾向、暴力倾向、不健康色彩的词或不文明的词语,对于文章中出现的敏感词常用的处理方法是使用特殊符号(如“*”)对敏感词进行替换。本实例要求编写代码,实现具有过滤敏感词功能的程序。
ch = '暴力''你好' #敏感词
test =input('请输入一段话:')
for line in ch:
if line in ch:
test = test.replace(line,'*')
print(test)
运行结果:
4.5.2 文字排版工具
文字排版工具是一款强大的文章自动排版工具,它会将文字按现代汉语习惯及发表出版要求进行规范编排。文字排版工具一般具备删除空格、英文标点替换、英文单词大写功能,本实例要求编写代码,实现具有上述功能的文字排版工具。
string = input('请输入一句话:')
print('1.删除空格')
print('2.英文标点替换')
print('3.英文单词大写')
print('4.退出')
while True:
option = input('请输入功能选项:\n')
if option=='1':
string = string.replace(' ','')
print(string)
elif option=='2':
string = string.replace(',',',')
string = string.replace('.', '。')
string = string.replace('"', '“')
print(string)
elif option=='3':
string = string.upper()
print(string)
elif option=='4':
break
运行结果:
课后编程题1:编写程序,已知字符串s=‘AbcDeFGhIJ’,计算该字符中小写字母的数量
s = 'AbcDeFGhIJ'
num = 0
for i in range(len(s)):
if 'a'<=s[i]<='z':
num+=1
print('小写字母的个数为:%d'%num)
运行结果:
课后编程题2:编写程序,检查字符串“Life is short. I use python”中是否包含字符串“python”,若包含则替换为“Python”后输出新字符串。否则输出原字符串。
s = 'Life is short.I use python'
if 'python' in s:
print(s.replace('python','Python'))
else:
print(s)
运行结果:
第5章
5.4.1十大歌手
为丰富校园文化生活,学校拟组织一场歌手大赛,从参赛选手中选拔出十名相对突出的学生,授予“校园十大歌手”称号。比赛之中设置有评委组,每名选手演唱完毕之后会由评委组的十名评委打分。为保证比赛公平公正、防止作弊和恶意打分,计算得分(即平均分)时会先去掉最高分和最低分。
本案例要求编写程序,实现根据需求计算每位选手得分的功能。
# 评分列表
score_li = []
# 总分
total_score = 0
for i in range(1, 11):
score = float(input(f"请第{i}位评委输入评分:\n"))
score_li.append(score)
score_li.sort()
print(f"去掉最低分:{score_li[0]}")
print(f"去掉最高分:{score_li[len(score_li)-1]}")
# 去掉最低分
score_li.remove(score_li[0])
# 去掉最高分
score_li.pop()
for j in score_li:
total_score += j
print(f'选手最终得分为:{total_score/(len(score_li))}')
运行结果:
5.4.2神奇魔方阵
魔方阵又称纵横图,是一种n行n列、由自然数1~n×n组成的方阵,该方阵中的数符合以下规律:
(1)方阵中的每个元素都不相等。
(2)每行、每列以及主、副对角线上的个元素之和都相等。
本案例要求编写程序,输出一个5行5列的魔方阵。
n = 5
# 5*5二维列表
magic_square = [[0 for x in range(n)]
for y in range(n)]
i = n / 2
j = n - 1
num = 1
while num <= (n * n):
if i == -1 and j == n:
j = n - 2
i = 0
else:
if j == n:
j = 0
if i < 0:
i = n - 1
if magic_square[int(i)][int(j)]:
j = j - 2
i = i + 1
continue
else:
magic_square[int(i)][int(j)] = num
num = num + 1
j = j + 1
i = i - 1
for i in range(0, n):
for j in range(0, n):
print('%2d ' % (magic_square[i][j]),end='')
if j == n - 1:
print()
运行结果:
5.7.1青春有你
如今两年偶像选秀节目风头正盛,吸引了许多喜欢唱跳、有明星梦想的少男少女参加,青春有你正是节目之一。青春有你采用计票机制,选手获得的票数越多,排名就越靠前。本案例要求编写程序,接收选手的姓名和票数,输出排序后的成绩。
player_info = {}
li = []
print('输入quit表示选手成绩录入完毕')
while True:
name = input("请输入选手名称:\n")
if name == 'quit':
break
score = float(input("请输入选手票数:\n"))
player_info[name] = score
items = player_info.items()
for j in items:
li.append([j[1], j[0]])
# 转换为list类型,进行排序
li.sort()
# 获取选手索引
count = len(li) – 1
# 输出排名
for i in range(1, len(li) + 1):
print(f"第{i}名:{li[count][1]},成绩为{li[count][0]}分")
count -= 1
运行结果:
5.7.2手机通讯录
通讯录是记录了联系人姓名和联系方式的名录,手机通讯录是最常见的通讯录之一,人们可以在通讯录中通过姓名查看相关联系人的联系方式,也可以在其中新增、修改或删除联系人信息。
本案例要求编写程序,实现具备添加、查看、修改以及删除联系人信息功能的手机通讯录。
person_info = []
print("=" * 20)
print('欢迎使用通讯录:')
print("1.添加联系人")
print("2.查看通讯录")
print("3.删除联系人")
print("4.修改联系人信息")
print("5.查找联系人")
print("6.退出")
print("=" * 20)
while True:
per_dict = {}
fun_num = input('请输入功能序号:')
if fun_num == '1':
per_name = input('请输入联系人的姓名:')
phone_num = input('请输入联系人的手机号:')
per_email = input('请输入联系人的邮箱:')
per_address = input('请输入联系人的地址:')
# 判断输入的是否为空
if per_name.strip() == '':
print('请输入正确信息')
continue
else:
per_dict.update({'姓名': per_name,
'手机号': phone_num,
'电子邮箱': per_email,
'联系地址': per_address})
person_info.append(per_dict) # 保存到列表中
print('保存成功')
elif fun_num == '2':
if len(person_info) == 0:
print('通讯录无信息')
for i in person_info:
for title, info in i.items():
print(title + ':' + info)
elif fun_num == '3': # 删除
if len(person_info) != 0:
del_name = input('请输入要删除的联系人姓名:')
for i in person_info:
if del_name in i.values():
person_info.remove(i)
print(person_info)
print('删除成功')
else:
print('该联系人不在通讯录中')
else:
print('通讯录无信息')
elif fun_num == '4': # 修改
if len(person_info) != 0:
modi_info = input('请输入要修改联系人姓名:')
for i in person_info:
if modi_info in i.values():
# 获取所在元组在列表中的索引位置
index_num = person_info.index(i)
dict_cur_perinfo = person_info[index_num]
for title, info in dict_cur_perinfo.items():
print(title + ':' + info)
modi_name = input('请输入新的姓名:')
modi_phone = input('请输入新的手机号:')
modi_email = input('请输入新的邮箱:')
modi_address = input('请输入新的地址:')
dict_cur_perinfo.update(姓名= modi_name)
dict_cur_perinfo.update(手机号= modi_phone)
dict_cur_perinfo.update(电子邮箱= modi_email)
dict_cur_perinfo.update(联系地址= modi_address)
print(person_info)
else:
print('通讯录无信息')
elif fun_num == '5': # 查找
if len(person_info) != 0:
query_name = input('请输入要查找的联系人姓名:')
for i in person_info:
if query_name in i.values():
index_num = person_info.index(i)
for title, info in person_info[index_num].items():
print(title + ':' + info)
break
else:
print('该联系人不在通讯录中')
else:
print('通讯录无信息')
elif fun_num == '6': # 退出
break
运行结果:
课后编程1:。已知列表li_num1=[4,5,2,7]和li_num2=[3,6],请将这两个列表合并为一个列表,并将合并后的列表中的元素按降序排序。
li_num1=[4,5,2,7]
li_num2=[3,6]
li_num3=li_num1+li_num2
print(f"合并后的列表为:{li_num3}")
li_num3.sort(reverse=True) #降序排序
print(f"排序后的列表为:{li_num3}")
运行结果:
课后编程2: 已知元组tu_num1 = ('p','y','t',['o','n']),请向元组的最后一个列表中添加新元素‘h’
tu_num1 = ('p','y','t',['o','n']) #元组是不可变类型,元组中的元素不能修改
list = list(tu_num1[3]) #list()函数接收一个可迭代类型的数据,返回一个列表
list.append('h') #append()用于在列表末尾添加新元素;extend()用于在列表末尾一次性添加另一个列表中的所有元素;insert()用于按照索引将新元素插入到列表指定位置
print(list)
tu_num1 = tu_num1[:3]+(list,) #更新元组
print(tu_num1)
运行结果:
课后编程3:已知字符串str='skdaskerkjsalkj',请统计该字符串中各字母出现的次数
str='skdaskerkjsalkj'
resoult = {} #定义一个空字典
for i in str: #遍历输入的字符串,以键值对的方式存储在字典中
resoult[i]=str.count(i)
for key in resoult: #遍历字典,格式化输出结果
print(f'"{key}":出现{resoult[key]}次')
运行结果:
课后编程4:已知列表li_one = [1,2,1,2,3,5,4,3,5,7,4,7,8],请删除列表li_one中的重复数据
li_one = [1,2,1,2,3,5,4,3,5,7,4,7,8]
li_two = []
for i in li_one:
if not i in li_two:
li_two.append(i)
print(li_two)
运行结果:
第6章
6.6.1角谷猜想
角谷猜想又称冰雹猜想,是由日本数学家角谷静发现的一种数学现象,它的具体内容是:以一个正整数n为例,如果n为偶数,就将它变为n/2,如果除后变为奇数,则将它乘3加1(即3n+1)。不断重复这样的运算,经过有限步后,必然会得到1。据日本和美国的数学家攻关研究,所有小于7×1011的自然数,都符合这个规律。
本案例要求编写代码,计算用户输入的数据按照以上规律经多少次运算后可变为1。
def guess(number):
i = 0 # 统计变换的次数
original_number = number # 记录最初的number
while number != 1:
if number % 2 == 0: # number为偶数
number = number / 2
else: # number为奇数
number = number * 3 + 1
i += 1
print(f"{original_number}经过{i}次变换后回到1")
num = int(input("请输入一个大于1的正整数:"))
guess(num)
运行结果:
6.6.2 饮品自动售货机
随着无人新零售经济的崛起,商场、车站、大厦等各种场所都引入了无人饮品自动售货机,方便人们选购自己想要的饮品。购买者选择想要的饮品,通过投币或扫码的方式支付,支付成功后从出货口取出饮品。本案例要求编写代码,利用函数实现具有显示饮品信息、计算总额等功能的程序。
# 饮品信息
def all_goods():
goods = {"可口可乐": 2.5, "百事可乐": 2.5, "冰红茶": 3, "脉动": 3.5,
"果缤纷": 3, "绿茶": 3, "茉莉花茶": 3, "尖叫": 2.5}
return goods
# 展示饮品信息
def show_goods():
for x, y in all_goods().items():
print(x, ":", str(y) + "元")
# 计算总额
def total(goods_dict):
count = 0
for name, num in goods_dict.items():
total_money = all_goods()[name] * num
# 总金额
count += total_money
print("需要支付金额:", count, "元")
def main():
goods_dict = {}
print("饮 品 自 动 售 货 机")
show_goods()
# 循环选购的商品
print("输入q完成购买")
while True:
goods_name = input("请输入购物的商品:")
if goods_name == 'q':
break
if goods_name in [g_name for g_name in all_goods().keys()]:
goods_num = input("请输入购物数量:")
if goods_num.isdigit():
goods_dict[goods_name] = float(goods_num)
else:
print('商品数量不合法')
else:
print('请输入正确的商品名称')
total(goods_dict)
if __name__ == '__main__':
main()
运行结果:
6.8.1兔子数列
兔子数列又称斐波那契数列、黄金分割数列,它由数学家列昂纳多·斐波那契以兔子繁殖的例子引出,故此得名。兔子繁殖的故事如下:
兔子一般在出生两个月之后就有了繁殖能力,每对兔子每月可以繁殖一对小兔子,假如所有的兔子都不会死,试问一年以后一共有多少对兔子?
本案例要求编写代码,利用递归实现根据月份计算兔子总数量的功能。
def fibonacci(month):
if month == 0 or month == 1:
return 1
else:
return fibonacci(month-1) + fibonacci(month-2)
# 测试经过12个月份后的兔子对数
result = fibonacci(12)
print(result)
运行结果:
6.8.2归并排序
归并排序是一种基于归并算法的排序方法,该方法采用分治策略:先将待排序的序列划分成若干长度为1的子序列,依次将两个子序列排序后合并成长度为2的子序列;再依次将两个子序列排序后合并成长度为4的子序列,直至合并成最初长度的序列为止,得到一个排序后的序列。例如,列表[8, 4, 5, 7, 1, 3, 6, 2]的元素采用归并排序的方法进行排列的过程如图6-5所示。
def merge_sort(li):
n = len(li)
if n == 1:
return li
# 把数据分成左右两部分
mid = n // 2
left = li[:mid]
right = li[mid:]
# 递归拆分
left_res = merge_sort(left)
right_res = merge_sort(right)
# 把下层返回上来的数据,组成有序序列
result = merge(left_res, right_res)
# 合并
return result
def merge(left, right):
result = []
left_index = 0
right_index = 0
while left_index < len(left) and right_index < len(right):
if left[left_index] <= right[right_index]:
result.append(left[left_index])
left_index += 1
else:
result.append(right[right_index])
right_index += 1
# while循环结束后,把剩下的数据添加进来
result += right[right_index:]
result += left[left_index:]
return result
if __name__ == '__main__':
list_demo = [6, 5, 7, 4, 3, 1]
print(merge_sort(list_demo))
运行结果:
6.9 阶段案例——学生管理系统
学生信息是高等院校的一项重要数据资源,具有数量庞大、学员广泛、更新频繁等特点,给管理人员带来了不小的冲击。随着计算机应用的普及,人们使用计算机设计了针对学生信息特点及实际需要的学生管理系统,使用该系统可以高效率地、规范地管理大量的学生信息,减轻了管理人员的工作负担。本案例要求开发一个具有添加、删除、修改、查询学生信息及退出系统功能的简易版学生管理系统,该系统的功能菜单如图6-6所示。
# print_menu():用于打印学生管理系统的功能菜单;
# add_stu_info():用于添加学生的信息;
# del_stu_info():用于删除学生的信息;
# modify_stu_info():用于修改学生的信息;
# show_stu_info():用于显示所有学生的信息;
# main():主程序,用于控制一次使用学生管理系统的完整流程。
# 保存所有的学生信息
stu_info = []
# 打印功能菜单
def print_menu():
print('=' * 30)
print('学生管理系统 V10.0')
print('1.添加学生信息')
print('2.删除学生信息')
print('3.修改学生信息')
print('4.查询所有学生信息')
print('0.退出系统')
print('=' * 30)
# 添加学生信息
def add_stu_info():
# 提示并获取学生的姓名
new_name = input('请输入新学生的姓名:')
# 提示并获取学生的性别
new_sex = input('请输入新学生的性别:')
# 提示并获取学生的手机号
new_phone = input('请输入新学生的手机号码:')
new_info = dict()
new_info['name'] = new_name
new_info['sex'] = new_sex
new_info['phone'] = new_phone
stu_info.append(new_info)
# 删除学生信息
def del_stu_info(student):
del_num = int(input('请输入要删除的序号:')) - 1
del student[del_num]
print("删除成功!")
# 修改学生信息
def modify_stu_info():
if len(stu_info) != 0:
stu_id = int(input('请输入要修改学生的序号:'))
new_name = input('请输入要修改学生的姓名:')
new_sex = input('请输入要修改学生的性别:(男/女)')
new_phone = input('请输入要修改学生的手机号码:')
stu_info[stu_id - 1]['name'] = new_name
stu_info[stu_id - 1]['sex'] = new_sex
stu_info[stu_id - 1]['phone'] = new_phone
else:
print('学生信息表为空')
# 显示所有的学生信息
def show_stu_info():
print('学生的信息如下:')
print('=' * 30)
print('序号 姓名 性别 手机号码')
i = 1
for tempInfo in stu_info:
print("%d %s %s %s" % (i, tempInfo['name'],
tempInfo['sex'], tempInfo['phone']))
i += 1
# 在main函数中执行不同的功能
def main():
while True:
print_menu() # 打印功能菜单
key = input("请输入功能对应的数字:") # 获取用户输入的序号
if key == '1': # 添加学生信息
add_stu_info()
elif key == '2': # 删除学生信息
del_stu_info(stu_info)
elif key == '3': # 修改学生信息
modify_stu_info()
elif key == '4': # 查询所有学生信息
show_stu_info()
elif key == '0':
quit_confirm = input('亲,真的要退出么?(Yes or No):').lower()
if quit_confirm == 'yes':
print("谢谢使用!")
break # 跳出循环
elif quit_confirm == 'no':
continue
else:
print('输入有误!')
if __name__ == '__main__':
main()
运行结果:
课后编程1:编写函数,输出1~100中偶数之和
sum=0
for i in range(1,101):
if i%2==0:
sum += i
print(sum)
运行截图:
课后编程2:编写函数,计算20*19*18*…*3的结果
def f(): #def关键字:函数的开始标志
s=1
for i in range(20,2,-1): #20为开始值,默认从0开始;2为结束值的下标;-1为步进值数据之间相隔
s*=i
return s #return返回函数的处理结果给调用方,是函数结束的标志,若没有返回值,可省略
print(f())
运行截图:
课后编程3:编写程序,判断用户输入的整数是否是回文数。回文数是一个正向和逆向都相同的整数,如123454321。
def test(num):
if not isinstance(num,int): #isinstance()判断一个对象是否是一个已知的类型
print("请输入一个整数!")
else:
num=str(num)
value = num[::1]
if value == num:
print("{}是回文数".format(num))
else:
print("{}不是回文数".format(num))
num = int(input("请输入一个正整数:"))
test(num)
运行截图:
课后编程4:编写函数,判断用户输入的3个数字是否能构成三角形的三条边。
def test(a,b,c):
if a<=0 or b<=0 or c<=0:
print("三角形的边必须大于0")
elif a+b<=c or b+c<=a or a+c<=b:
print("两边之和应该大于第三边")
else:
print("输入的三条边符合三角形的规则")
a = float(input("请输入边长a:"))
b = float(input("请输入边长b:"))
c = float(input("请输入边长c:"))
test(a,b,c)
运行截图:
课后编程5:编写函数,求2个正整数的最小公倍数。
def fangfa(a,b):
if a>b:
bigger=a
smaller=b
else:
bigger=b
smaller=a
i=1
while True:
if (bigger*i)%smaller==0: #如果大的那个数,一旦他的倍数能整除小的那个数,就直接跳出循环,他的倍数就是最小公倍数
print('最小公倍数为:',(bigger*i))
break
i+=1
if __name__ == '__main__':
a = int(input('请输入第一个数:'))
b = int(input('请输入第二个数:'))
fangfa(a,b)
运行截图:
第7章
7.4.1安全策略——文件备份
当下是信息时代,信息在当今社会占据的地位不言而喻,信息安全更是当前人类重视的问题之一。人类考虑从传输和存储两方面保障信息的安全,备份是在存储工作中保障信息安全的有效方式。本案例要求编写程序,实现一个具有备份文件与文件夹功能的备份工具。
import os
def file_backups(file_name, path):
# 备份的文件名
file_back = file_name.split('\\')[-1]
# 判断用户输入的内容是文件还是文件夹
if os.path.isdir(file_name) is not True:
with open(file_name, mode='r') as file_data:
# 创建新文件 , 以只读的方式打开
new_path = path + '/' + file_back
with open(new_path, 'w') as file_back:
# 逐行复制源文件内容到新文件中
for line_content in file_data.readlines():
file_back.write(line_content)
# 判断是目录还是文件
def judge(back_path, file_path):
if os.path.isdir(file_path) is True:
# 遍历当前目录下的文件
file_li = os.listdir(file_path)
for i in file_li:
# 拼接文件名称
new_file = file_path + '\\' + i
file_backups(new_file, back_path)
else:
# 是文件
if os.path.exists((file_path)):
file_backups(file_path, back_path)
else:
print("备份的文件不存在!")
exit()
# 备份目录
def backups_catalog():
# 指定备份的目录
back_path = input("请输入备份的目录:\n")
file_path = input("请输入备份的文件:\n")
# 指定目录不存在
if os.path.exists(back_path) is False:
os.mkdir(back_path) #mkdir()创建目录
judge(back_path, file_path)
print('备份成功!')
# 指定目录存在
else:
judge(back_path, file_path)
print('备份成功!')
if __name__ == '__main__':
backups_catalog()
运行截图:
7.4.2 用户账户管理
某些网站要求访问者在访问网站内容之前必须先进行登录,若用户没有该网站的账号,则需要先进行注册。用户注册完账号后,网站的服务器会保存账号信息,以便用户下次访问网站时网站可根据保存的信息验证用户的身份。为保障账户安全,用户可时常修改密码;若后续用户不再使用网站,可以选择注销账户。
本案例要求实现包含用户注册、登录、修改密码和注销功能的用户账户管理程序(要求程序使用文件存储用户的账户信息)。
import os
# 将文件中的数据转换为字典
def convert_data():
info_li = []
with open('info.txt', mode='r+', encoding='utf8') as f:
info_data = f.readlines()
for i in info_data:
info_dict = dict()
# 替换{ 和 } 并去掉空格
step_one = i.replace('{', '').replace('}', '')
# 以冒号进行分隔
step_two = step_one.split(':')
# 拼接字典
info_dict["姓名"] = step_two[1].split(',')[0].replace("'", '').strip()
info_dict["密码"] = step_two[2].replace("'", '').strip()
# 保存到列表中
info_li.append(info_dict)
return info_li
# 注册
def register():
if os.path.exists('info.txt') is not True:
with open('info.txt', mode='w', encoding='utf8') as f:
f.write('')
# 用户名列表
name_li = []
info_li = convert_data()
# 接收注册信息
person_info = {}
name = input("请输入注册用户名:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if name in name_li:
print('用户已注册')
else:
password = input("请输入注册密码:\n")
person_info['姓名'] = name
person_info['密码'] = password
# 写入注册信息
with open('info.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(person_info) + '\n')
# 登录
def login():
if os.path.exists('info.txt') is not True:
print('当前无数据,请先注册')
else:
# 用户名列表
name_li = []
info_li = convert_data()
name = input("请输入登录用户名:\n")
password = input("请输入登录密码:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if name in name_li:
# 获取修改用户的索引
modify_index = name_li.index(name)
# 判断密码是否正确
if password == info_li[modify_index]['密码']:
print('登录成功')
else:
print('用户名或密码不正确')
else:
print('用户名或密码不正确')
# 注销
def cancel():
if os.path.exists('info.txt') is not True:
print('当前无数据,请先注册')
else:
cancel_name = input("请输入注销的用户\n")
cancel_password = input("请输入密码\n")
# 用户名列表
name_li = []
info_li = convert_data()
for i in info_li:
name_li.append(i['姓名'])
if cancel_name in name_li:
# 获取注销用户的索引
cancel_index = name_li.index(cancel_name)
# 判断输入的密码是否正确
if cancel_password == info_li[cancel_index]['密码']:
info_li.pop(cancel_index)
# 写入空数据
with open('info.txt', mode='w+', encoding='utf8') as f:
f.write('')
for i in info_li:
with open('info.txt', mode='a+', encoding='utf8')as info_data:
info_data.write(str(i) + '\n')
print('用户注销成功')
else:
print('用户名或密码不正确')
else:
print('注销的用户不存在')
# 修改密码
def modify():
if os.path.exists('info.txt') is not True:
print('当前无数据,请先注册')
else:
# 用户名列表
name_li = []
info_li = convert_data()
modify_name = input("请输入用户名:\n")
password = input("请输入旧密码:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if modify_name in name_li:
# 获取修改密码用户的索引
modify_index = name_li.index(modify_name)
# 判断密码是否正确
if password == info_li[modify_index]['密码']:
# 修改密码
new_password = input("请输入新密码\n")
info_li[modify_index]['密码'] = new_password
with open('info.txt', mode='w+', encoding='utf8') as f:
f.write('')
for i in info_li:
with open('info.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(i) + '\n')
else:
print("用户名或密码不正确")
else:
print("用户名或密码不正确")
def welcome():
print("欢迎使用账户管理程序")
print("1.用户注册")
print("2.用户登录")
print("3.用户注销")
print("4.修改密码")
print("5.退出")
while True:
option = input("请选择功能\n")
# 用户注册
if option == '1':
register()
# 用户登录
elif option == '2':
login()
# 注销
elif option == '3':
cancel()
# 修改密码
elif option == '4':
modify()
elif option == '5':
break
if __name__ == '__main__':
welcome()
运行截图:
课后编程1:读取一个文件,打印除以字符#开头的行之外的所有行。
name = input('请输入文件名或文件路径:')
file = open(name,'r')
r=file.readlines()
for i in r:
if i[0]=='#':
continue
else:
print(i)
file.close()
运行截图:
课后编程2:编写程序,实现文件备份功能。
#1.用户输入目标文件
old_name=input('请输入你要备份的文件名:')
#提取后缀 找到名字中的点 名字和后缀分离 最右侧的点才是后缀点 查找某个字符串
index = old_name.rfind('.')
if index>0:
postfix = old_name[index:] #提取后缀
#新名字=原名字+[备份]+后缀
new_name=old_name[:index]+'[备份]'+postfix
#备份文件写入数据(数据和原文件一样)
old_f=open(old_name,'rb') #rb只读
new_f=open(new_name,'wb') #wb只写
#原文件读取,备份文件写入
while True:
content = old_f.read(1024)
if len(content)==0:
break
new_f.write(content)
old_f.close()
new_f.close()
运行截图:
课后编程3:编写程序,读取一个存储若干数字的文件,对其中的数字排序后输出
#只能读取一行数字
name = input('请输入文件名或文件路径:')
file = open(name,'r')
con = file.read()
print(f'排序前文件中的数字:{con}')
filelist=list(con)
filelist.sort()
file.close()
print('排序后文件中的数字:'+''.join(filelist))
运行截图:
第8章
实训案例:
8.5.1 好友管理
如今的社交软件层出不穷,虽然功能千变万化,但都具有好友管理系统的基本功能,包括添加好友、删除好友、备注好友、展示好友、好友分组功能。下面是一个简单的好友管理系统的功能菜单,如图1所示。
图1中的好友管理系统中有5个功能,每个功能都对应一个序号,用户可根据提示“请输入您的选项”选择序号执行相应的操作,包括:
添加好友:用户根据提示“请输入要添加的好友:”输入要添加好友的姓名,添加后会提示“好友添加成功”。
删除好友:用户根据提示“请输入删除好友姓名:”输入要删除好友的姓名,删除后提示“删除成功”。
备注好友:用户根据提示“请输入要修改的好友姓名:”和“请输入修改后的好友姓名:”分别输入修改前和修改后的好友姓名,修改后会提示“备注成功”。
展示好友:展示用户功能分为展示所有好友和展示分组中的好友,如果用户选择展示所有好友,那么展示将好友列表中的所有好友进行展示;如果用户选择展示分组好友,那么根据用户选择的分组名展示此分组中的所有好友。
好友分组:好友分组功能用于将好友划分为不同的组,执行好友分组功能会提示用户是否创建新的分组。
退出:关闭好友管理系统。
本实例要求编写程序,实现如上所述功能的好友管理系统。
class Friend:
def __init__(self):
self.friend_li = []
def welcome(self):
print('** 欢迎使用好友管理系统 **')
print('1:添加好友')
print('2:删除好友')
print('3:备注好友')
print('4:展示好友')
print('5:好友分组')
print('6:退出')
while True:
options = input("请选择功能\n")
# 添加好友
if options == '1':
self.add_friend()
elif options == '2':
self.del_friend()
elif options == '3':
self.modify_friend()
elif options == '4':
self.show_friend()
elif options == '5':
self.group_friend()
elif options == '6':
break
def add_friend(self):
add_friend = input("请输入要添加的好友:")
self.friend_li.append(add_friend)
print('好友添加成功')
def get_all_friends(self):
new_li = []
for friend_li_elem in self.friend_li:
# 判断元素类型
if type(friend_li_elem) == dict:
# 遍历字典
[new_li.append(dict_elem_name) for
dict_elem in friend_li_elem.values()
for dict_elem_name in dict_elem]
else:
new_li.append(friend_li_elem)
return new_li
def get_all_groups(self):
groups = []
for friend_li_elem in self.friend_li:
if type(friend_li_elem) == dict:
groups.append(friend_li_elem)
return groups
def get_all_groups_name(self):
groups_name = []
for dict_elem in self.get_all_groups():
for j in dict_elem:
groups_name.append(j)
return groups_name
def del_friend(self):
if len(self.friend_li) != 0:
del_name = input("请输入删除好友姓名:")
# 删除的好友未分组
if del_name in self.friend_li:
self.friend_li.remove(del_name)
print('删除成功')
else:
# 删除的好友在分组内
if del_name in self.get_all_friends():
for group_data in self.get_all_groups():
for group_friend_li in group_data.values():
if del_name in group_friend_li:
group_friend_li.remove(del_name)
continue
print('删除成功')
else:
print('好友列表为空')
def modify_friend(self):
friends = self.get_all_friends()
if len(friends) == 0:
print('好友列表为空')
else:
before_name = input("请输入要修改的好友姓名:")
after_name = input("请输入修改后的好友姓名:")
if before_name in self.friend_li:
friend_index = self.friend_li.index(before_name)
self.friend_li[friend_index] = after_name
print("备注成功")
elif before_name not in self.friend_li:
for friend_li_elem in self.friend_li:
if type(friend_li_elem) == dict:
for dict_elem in friend_li_elem.values():
if before_name in dict_elem:
modify_index = dict_elem.index(before_name)
dict_elem[modify_index] = after_name
print('备注成功')
def show_friend(self):
print("1.展示所有好友")
print("2.展示分组名称")
option_show = input("请输入选项:")
groups = self.get_all_groups()
friends = self.get_all_friends()
if option_show == '1':
# 展示所有好友
if len(friends) == 0:
print("当前没有任何好友")
else:
print(friends)
elif option_show == '2':
if len(friends) == 0:
print("当前没有任何好友")
else:
if len(groups) == 0:
print("当前没有任何分组")
else:
# 展示分组
for dict_groups in groups:
for group_name in dict_groups:
print(group_name)
is_show_group = input("是否展示组内好友:y/n\n")
if is_show_group == 'y':
show_group_name = input("请输入查看的分组名称")
for i in groups:
if show_group_name in i:
show_index = groups.index(i)
print(groups[show_index][show_group_name])
def group_friend(self):
create_group = input("是否创建新的分组y/n\n")
friends = self.get_all_friends()
if create_group == 'y':
if len(friends) == 0:
print("当前没有任何好友")
else:
# 请创建分组
group_name = input("请输入分组名称:\n")
group_name_li = list()
# 展示当前好友
print(friends)
# 移动联系人到哪个组
friend_name = input("请输入好友名称:\n")
if friend_name in friends:
all_friend = []
for friend_li_elem in self.friend_li:
if type(friend_li_elem) == dict:
[all_friend.append(dict_friends) for
dict_elem in friend_li_elem.values()
for dict_friends in dict_elem]
else:
all_friend.append(friend_li_elem)
if friend_name in all_friend:
group_name_li.append(friend_name)
self.friend_li.remove(friend_name)
# 构建字典: {组名称:分组列表}
friend_dict = dict()
friend_dict[group_name] = group_name_li
self.friend_li.append(friend_dict)
else:
print("请输入正确的名称")
else:
print('请输入正确好友名称')
elif create_group == 'n':
# 显示当前的分组,将用户添加到指定的组
current_groups = self.get_all_groups()
print('当前分组:')
for current_group in current_groups:
for group_name in current_group:
print(group_name)
add_group = input('请选择添加的组:\n')
# 判断用户输入的组名是否在当前已存在的分组名中
if add_group in self.get_all_groups_name():
# 添加好友到指定的组
add_name = input('请选择添加的好友名称:\n')
# 判断用户输入的好友是否存在好友列表中
if add_name in self.friend_li:
# 判断用户是否在其他组中
if add_name not in current_groups:
# 将好友添加到指定的组内
add_group_index = \
self.get_all_groups_name().index(add_group)
current_groups[add_group_index][
add_group].append(add_name)
else:
print('该好友已在其他分组中')
else:
print('请输入正确的组名')
if __name__ == '__main__':
friend = Friend()
friend.welcome()
运行结果:
8.5.2生词本
背单词是英语学习中最基础的一环,不少用户在背诵单词的过程中会记录生词,以不断拓展自己的词汇量。生词本是一款专门为用户背单词而设计的软件,它有包含用户模块和单词记录模块,其中用户模块包括用户注册、用户登录、用户注销、修改密码和退出功能;单词记录模块包括查看单词、背单词、添加新单词、删除单词、清空单词和退出功能。用户模块会将用户注册的数据会保存到info.txt中;单词记录模块中的数据会将保存的单词以注册的用户名作为文件名进行保存。
本案例要求编写代码,实现一个基于面向对象思想的、具有上述功能的生词本程序。
生词本具体功能如图1所示。
import os
class User:
# 功能展示
def welcome(self):
print("欢迎使用生词本")
print("1.用户注册")
print("2.用户登录")
print("3.用户注销")
print("4.修改密码")
print("5.退出")
while True:
option = input("请选择功能(登录)\n")
# 用户注册
if option == '1':
self.register()
# 用户登录
elif option == '2':
self.login()
# 注销
elif option == '3':
self.cancel()
# 修改密码
elif option == '4':
self.modify()
elif option == '5':
print('谢谢使用')
break
# 将文件中的数据转换为字典
def convert_data(self):
info_li = []
with open('./info.txt', mode='r+', encoding='utf8') as f:
info_data = f.readlines()
for i in info_data:
info_dict = dict()
# 替换{ 和 } 并去掉空格
step_one = i.replace('{', '').replace('}', '')
# 以冒号进行分隔
step_two = step_one.split(':')
# 拼接字典
info_dict["姓名"] = step_two[1].split(',')[0].replace("'", '').strip()
info_dict["密码"] = step_two[2].split(',')[0].replace("'", '').strip()
# 保存到列表中
info_li.append(info_dict)
return info_li
# 注册
def register(self):
if os.path.exists('./info.txt') is not True:
with open('./info.txt', mode='w', encoding='utf8') as f:
f.write('')
# 用户名列表
name_li = []
info_li = self.convert_data()
# 接收注册信息
person_info = {}
name = input("请输入注册用户名:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if name in name_li:
print('用户已注册')
else:
password = input("请输入注册密码:\n")
person_info['姓名'] = name
person_info['密码'] = password
# 写入注册信息
with open('./info.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(person_info) + '\n')
# 登录
def login(self):
from recite import ReciteLogic
if os.path.exists('./info.txt') is not True:
print('当前无数据,请先注册')
else:
# 用户名列表
name_li = []
info_li = self.convert_data()
name = input("请输入登录用户名:\n")
password = input("请输入登录密码:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if name in name_li:
# 获取修改用户的索引
modify_index = name_li.index(name)
# 判断密码是否正确
if password == info_li[modify_index]['密码']:
print('登录成功')
ReciteLogic().welcome(name)
else:
print('用户名或密码不正确')
else:
print('用户名或密码不正确')
# 注销
def cancel(self):
if os.path.exists('./info.txt') is not True:
print('当前无数据,请先注册')
else:
cancel_name = input("请输入注销的用户\n")
cancel_password = input("请输入密码\n")
# 用户名列表
name_li = []
info_li = self.convert_data()
for i in info_li:
name_li.append(i['姓名'])
if cancel_name in name_li:
# 获取注销用户的索引
cancel_index = name_li.index(cancel_name)
# 判断输入的密码是否正确
if cancel_password == info_li[cancel_index]['密码']:
info_li.pop(cancel_index)
# 写入空数据
with open('./info.txt', mode='w+', encoding='utf8') as f:
f.write('')
for i in info_li:
with open('./info.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(i) + '\n')
print('用户注销成功')
else:
print('用户名或密码不正确')
else:
print('注销的用户不存在')
# 修改密码
def modify(self):
if os.path.exists('./info.txt') is not True:
print('当前无数据,请先注册')
else:
# 用户名列表
name_li = []
info_li = self.convert_data()
modify_name = input("请输入用户名:\n")
password = input("请输入旧密码:\n")
# 获取用户列名列表
for i in info_li:
name_li.append(i['姓名'])
# 判断用户是否存在
if modify_name in name_li:
# 获取修改密码用户的索引
modify_index = name_li.index(modify_name)
# 判断密码是否正确
if password == info_li[modify_index]['密码']:
# 修改密码
new_password = input("请输入新密码\n")
info_li[modify_index]['密码'] = new_password
with open('./info.txt', mode='w+', encoding='utf8') as f:
f.write('')
for i in info_li:
with open('./info.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(i) + '\n')
else:
print("用户名或密码不正确")
else:
print("用户名或密码不正确")
if __name__ == '__main__':
p = User()
p.welcome()
import os
class ReciteLogic:
def __init__(self):
self.user_name =''
# 首页
def welcome(self, name):
self.user_name = name
print('=' * 20)
print(name + '的生词记录本')
print('1.查看单词')
print('2.背单词')
print('3.添加新单词')
print('4.删除单词')
print('5.清空单词')
print('6.退出')
print('=' * 20)
while True:
option = input("请输入功能选项(生词本):\n")
if option == '1':
self.see_words()
elif option == '2':
self.recite_words()
elif option == '3':
self.add_words()
elif option == '4':
self.del_words()
elif option == '5':
self.clear_words()
elif option == '6':
break
# 文件中的数据转换为字典
def convert_data(self):
info_li = []
with open('./' + self.user_name + '.txt', mode='r+', encoding='utf8') as f:
info_data = f.readlines()
for i in info_data:
info_dict = dict()
# 替换{ 和 } 并去掉空格
step_one = i.replace('{', '').replace('}', '')
# 以冒号进行分隔
step_two = step_one.split(':')
en = step_two[0].split(',')[0].replace("'", '').strip()
zh = step_two[1].split(',')[0].replace("'", '').strip()
info_dict[en] = zh
# 保存到列表中
info_li.append(info_dict)
return info_li
# 查看单词
def see_words(self):
if os.path.exists('./' + self.user_name + '.txt') is not True:
print('当前无数据,请先添加单词')
else:
words_data = self.convert_data()
if len(words_data)==0:
print("生词本内容为空")
else:
# 读取文件数据
with open('./' + self.user_name + '.txt', mode='r+', encoding='utf8') as f:
info_data = f.readlines()
for i in info_data:
print(i.replace('{', '').replace('}', '').strip())
# 背单词
def recite_words(self):
if os.path.exists('./' + self.user_name + '.txt') is not True:
print('当前无数据,请先添加单词')
else:
words_data = self.convert_data()
if len(words_data) == 0:
print("生词本内容为空")
else:
words_li = self.convert_data()
# 所有英文单词
en_li = []
for i in words_li:
for j in i.keys():
en_li.append(j)
# 随机产生的英语单词
for random_word in set(en_li):
# 获取该单词在en_li中的索引
random_word_index = en_li.index(random_word)
# 获取该单词所对应的中文
words_zh = words_li[random_word_index][random_word]
in_words = input("请输入" + random_word + '翻译' + ':\n')
# 判断翻译是否正确
if in_words ==words_zh:
print('太棒了')
else:
print('再想想')
# 添加新单词
def add_words(self):
if os.path.exists('./' + self.user_name + '.txt') is not True:
with open('./' + self.user_name + '.txt', mode='w+', encoding='utf8') as f:
f.write('')
word_data_dict = dict()
new_words = input('请输入新单词:')
# 判断输入的单词是否已存在
words_li = self.convert_data()
# 所有英文单词
en_li = []
for i in words_li:
for j in i.keys():
en_li.append(j)
if new_words in en_li:
print('添加的单词已存在')
else:
translate = input('请输入单词翻译:')
if os.path.exists('./' + self.user_name + '.txt') is not True:
with open('./' + self.user_name + '.txt', mode='w', encoding='utf8') as f:
f.write('')
word_data_dict[new_words] = translate
with open('./' + self.user_name + '.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(word_data_dict) + "\n")
# 删除单词
def del_words(self):
if os.path.exists('./' + self.user_name + '.txt') is not True:
print('当前无数据,请先添加单词')
else:
words_data = self.convert_data()
if len(words_data) == 0:
print("生词本内容为空")
else:
words_li = self.convert_data()
# 所有英文单词
en_li = []
for i in words_li:
for j in i.keys():
en_li.append(j)
del_words = input("请输入要删除的单词:\n")
if del_words not in en_li:
print('删除的单词不存在')
else:
# 获取要删除单词的索引
del_words_index = en_li.index(del_words)
# 删除单词
words_li.pop(del_words_index)
print('单词删除成功')
# 重新写入数据
with open('./' + self.user_name + '.txt', mode='w+', encoding='utf8') as f:
f.write('')
for i in words_li:
with open('./' + self.user_name + '.txt', mode='a+', encoding='utf8') as info_data:
info_data.write(str(i) + '\n')
# 清空单词
def clear_words(self):
if os.path.exists('./' + self.user_name + '.txt') is not True:
print('当前无数据,请先添加单词')
else:
with open('./' + self.user_name + '.txt', mode='w+', encoding='utf8') as f:
f.write('')
运行结果:
8.10.1 人机猜拳游戏
相信大家对猜拳游戏都不陌生。猜拳游戏又称猜丁壳,是一个古老、简单、常用于解决争议的游戏。猜拳游戏一般包含三种手势:石头、剪刀、布,判定规则为石头胜剪刀,剪刀胜布,布胜石头。本案例要求编写代码,实现基于面向对象思想的人机猜拳游戏。
import random
class Player:
def __init__(self):
self.dict = {0: '剪刀', 1: '石头', 2: '布'}
# 手势
def gesture(self):
player_input = int(input("请输入(0剪刀、1石头、2布:)"))
return self.dict[player_input]
class AIPlayer(Player):
play_data = []
def ai_gesture(self):
while True:
computer = random.randint(0, 2)
if len(self.play_data) >= 4:
# 获取玩家出拳的最大概率
max_prob = max(self.play_data, key=self.play_data.count)
if max_prob == '剪刀':
return '石头'
elif max_prob == '石头':
return '布'
else:
return '剪刀'
else:
return self.dict[computer]
class Game:
def game_judge(self):
player = Player().gesture()
AIPlayer().play_data.append(player)
aiplayer = AIPlayer().ai_gesture()
if (player == '剪刀' and aiplayer == '布') or \
(player == '石头' and aiplayer == '剪刀') \
or (player == '布' and aiplayer == '石头'):
print(f"电脑出的手势是{aiplayer},恭喜,你赢了!")
elif (player == '剪刀' and aiplayer == '剪刀') or \
(player == '石头' and aiplayer == '石头') \
or (player == '布' and aiplayer == '布'):
print(f"电脑出的手势是{aiplayer},打成平局了!")
else:
print(f"电脑出的手势是{aiplayer},你输了,再接再厉!")
def game_start(self):
self.game_judge()
while True:
option = input("是否继续:y/n\n")
if option=='y':
self.game_judge()
else:
break
if __name__ == '__main__':
g = Game()
g.game_start()
运行结果:
8.10.2自定义列表
列表是Python内置的数据类型,它可以灵活地增加、删除、修改、查找其中的元素,但即使列表只包含数值,它仍不支持与数字类型进行四则运算。为使列表支持四则运算,我们可以自定义一个列表类,在该类中重载运算符,使列表中各元素分别与数值相加、相减、相乘或相除后所得的结果组成该列表的新元素。本案例要求编写代码,重载运算符,使列表支持四则运算。
"""
from custom_list import MyList
add_demo = MyList(1,2,3,4,5)
print(add_demo+5) 每个元素都加5,并返回新的列表
"""
class MyList:
def __isnumber(self, n):
if not isinstance(n, (int, float, complex)):
return False
return True
# 构造函数,进行必要的初始化
def __init__(self, *args):
for arg in args:
if not self.__isnumber(arg):
print('所有的元素必须是数字类型')
return
self.__value = list(args)
def __str__(self):
return str(self.__value)
def __del__(self):
del self.__value
# 重载运算符+
def __add__(self, num):
if self.__isnumber(num):
# 数组中所有元素都与数字num相加
my_list = MyList()
my_list.__value = [elem + num for elem in self.__value]
return my_list
# 重载运算符-
# 数组中每个元素都与数字num相减,返回新数组
def __sub__(self, num):
if not self.__isnumber(num):
print('所有的元素必须是数字类型')
return
my_list = MyList()
my_list.__value = [elem - num for elem in self.__value]
return my_list
# 重载运算符*
# 数组中每个元素都与数字num相乘,返回新数组
def __mul__(self, num):
if not self.__isnumber(num):
print('所有的元素必须是数字类型')
return
my_list = MyList()
my_list.__value = [elem * num for elem in self.__value]
return my_list
# 重载运算符/
# 数组中每个元素都与数字num相除,返回新数组
def __truediv__(self, num):
if not self.__isnumber(num):
print('所有的元素必须是数字类型')
return
my_list = MyList()
my_list.__value = [elem / num for elem in self.__value]
return my_list
from custom_list import MyList
add_demo = MyList(1,2,3,4,5)
print(add_demo+1)
print(add_demo-1)
print(add_demo*2)
print(add_demo/2)
print(add_demo+5)
运行结果:
8.11 阶段案例——银行管理系统
从早期的钱庄到现如今的银行,金融行业在不断地变革;随着科技的发展、计算机的普及,计算机技术在金融行业得到了广泛的应用。银行管理系统是一个集开户、查询、取款、存款、转账、锁定、解锁、退出等一系列的功能的管理系统,该系统中各功能的介绍如下。
开户功能:用户在ATM机上根据提示“请输入姓名:”、“请输入身份证号:”、“请输入手机号:”依次输入姓名、身份证号、手机号、预存金额、密码等信息,如果开户成功,系统随机生成一个不重复的6位数字卡号。
查询功能:根据用户输入的卡号、密码查询卡中余额,如果连续3次输入错误密码,该卡号会被锁定。
取款功能:首先根据用户输入的卡号、密码显示卡中余额,如果连续3次输入错误密码,该卡号会被锁定;然后接收用户输入的取款金额,如果取款金额大于卡中余额或取款金额小于0,系统进行提示并返回功能页面。
存款功能:首先根据用户输入的卡号、密码显示卡中余额,如果连续3次输入错误密码,该卡号会被锁定,然后接收用户输入的取款金额,如果存款金额小于0,系统进行提示并返回功能页面。
转账功能:用户需要分别输入转出卡号与转入卡号,如果连续3次输入错误密码,卡号会被锁定。当输入转账金额后,需要用户再次确认是否执行转账功能;如果确定执行转账功能,转出卡与转入卡做相应金额计算;如果取消转账功能,则回退之前操作。
锁定功能:根据输入的卡号密码执行锁定功能,锁定之后该卡不能执行查询、取款、存款、转账等操作。
解锁功能:根据输入的卡号密码执行解锁功能,解锁后能对该卡执行查询、取款、存款、转账等操作。
存盘功能:执行存盘功能后,程序执行的数据会写入本地文件中。
退出功能:执行退出功能时,需要输入管理员的账户密码,如果输入的账号密码错误,则返回功能页面,如果输入的账号密码正确,则执行存盘并退出系统。
本实例要求编写程序,实现一个具有上述功能的银行管理系统。
class Admin:
adminU = '1' # 管理员的账号
adpwd = '1' # 管理员的密码
def printAdminView(self):
print("******************************************")
print("*** ***")
print("*** ***")
print("*** 欢迎登录银行系统 ***")
print("*** ***")
print("*** ***")
print("******************************************")
def printsysFunctionView(self):
print("***********************************************")
print("*** ***")
print("*** 1.开户(1) 2.查询(2) ***")
print("*** 3.取款(3) 4.存款(4) ***")
print("*** 5.转账(5) 6.锁定(6) ***")
print("*** 7.解锁(7) ***")
print("*** ***")
print("*** 退出(Q) ***")
print("*** ***")
print("***********************************************")
def adminOption(self):
adminInput = input("请输入管理员账户:")
if self.adminU != adminInput:
print("管理员账户输入错误......")
return -1
passwordInput = input("请输入密码:")
if self.adpwd != passwordInput:
print("输入密码有误......")
return -1
else:
print("操作成功,请稍后......")
return 0
#ATM
from user import User
from card import Card
import random
class ATM:
def __init__(self, alluser):
self.alluser = alluser
#randomiCardId()方法的作用是在用户开户时生成随机银行卡号,该方法中需要借助random模块的函数生成随机数,也需要排除生成重复卡号的情况
def randomiCardId(self): # 随机生成开户卡号
while True:
str_data = '' # 存储卡号
for i in range(6): # 随机生成6位卡号
ch = chr(random.randrange(ord('0'), ord('9') + 1))
str_data += ch
if not self.alluser.get(str): # 判断卡号是否重复
return str_data
#creatUser()方法用于为用户开设账户,在该方法中需要用户先根据提示信息依次输入姓名、身份证号、手机号、预存金额(必须大于0,否则提示“开户失败”),再连续输入两次银行卡的密码(必须一致,否则因开户失败重新回到功能界面),最后随机生成开户卡号,根据该卡号创建卡信息和用户信息,并将用户的信息存储到alluser中
def creatUser(self):
# 目标向用户字典中添加一个键值对(卡号、用户对象)
name = input("请输入姓名:")
Uid = input("请输入身份证号:")
phone = input("请输入手机号:")
prestMoney = float(input("请输入预存金额:"))
if prestMoney <= 0:
print("预存款输入有误,开户失败")
return -1
oncePwd = input("请输入密码:")
passWord = input("请再次输入密码:")
if passWord != oncePwd:
print("两次密码输入不同......")
return -1
print("密码设置成功,请牢记密码: %s " % passWord)
cardId = self.randomiCardId()
card = Card(cardId, oncePwd, prestMoney) # 创建卡
user = User(name, Uid, phone, card) # 创建用户
self.alluser[cardId] = user # 存入用户字典
print("您的开户已完成,请牢记开户账号: %s" % cardId)
#creatUser()方法用于核对用户输入的密码,且限定至多输入3次,超过三次则返回False,输入正确则返回True
def checkpwg(self, realPwd):
for i in range(3):
psd2 = input("请输入密码:")
if realPwd == psd2:
return True
print("密码输错三次,系统自动退出......")
return False
#lockCard()方法用于在用户主要要求锁定银行卡
def lockCard(self):
inptcardId = input("请输入您的卡号:")
user = self.alluser.get(inptcardId)
if not self.alluser.get(inptcardId):
print("此卡号不存在...锁定失败!")
return -1
if user.card.cardLock:
print("该卡已经被锁定,无需再次锁定!")
return -1
if not self.checkpwg(user.card.cardPwd): # 验证密码
print("密码错误...锁定失败!!")
return -1
user.card.cardLock = True
print("该卡被锁定成功!")
#searchUser ()方法实现查询余额的功能,确保用户在发生存钱、取钱和转账行为之前能输入正确的银行卡号,以及银行卡处于非锁定状态,此时返回拥有该银行卡的用户,否则返回-1
def searchUser(self, base=1):
if base == 2:
inptcardId = input("请输入转出主卡号:")
elif base == 3:
inptcardId = input("请输入转入卡号:")
elif base == 1:
inptcardId = input("请输入您的卡号:")
user = self.alluser.get(inptcardId)
# 如果卡号不存在,下面代码就会执行
if not self.alluser.get(inptcardId):
print("此卡号不存在...查询失败!")
return -1
if user.card.cardLock:
print("该用户已经被锁定...请解卡后使用!")
return -1
if not self.checkpwg(user.card.cardPwd): # 验证密码
print("密码错误过多...卡已经被锁定,请解卡后使用!")
user.card.cardLock = True
return -1
if not base == 3: # 查询转入账户 不打印余额
print("账户: %s 余额: %.2f " % (user.card.cardId, user.card.money))
return user
#getMoney ()方法实现用户使用银行管理系统取钱的功能,该方法中首先需调用searchUser ()方法根据用户输入的卡号返回拥有该卡的用户,然后处理用户输入不同金额的情况
def getMoney(self):
userTF = self.searchUser()
if userTF != -1:
if userTF.card.cardId != '':
inptMoney = float(input("请输入取款金额:"))
if inptMoney > int(userTF.card.money):
print("输入的金额大于余额,请先查询余额!")
return -1
userTF.card.money = float(userTF.card.money) - inptMoney
print("取款成功! 账户: %s 余额: %.2f " %
(userTF.card.cardId, userTF.card.money))
else:
return -1
#saveMoney()方法实现用户使用银行管理系统存钱的功能,与getMoney ()方法的功能类似
def saveMoney(self):
userTF = self.searchUser()
if userTF != -1:
if not userTF.card.cardLock == True:
if userTF.card.cardId != '':
inptMoney = float(input("请输入要存入得金额:"))
if inptMoney < 0:
print("请输入正确金额")
else:
userTF.card.money += inptMoney
print("存款成功! 账户: %s 余额: %.2f " %
(userTF.card.cardId, userTF.card.money))
else:
return -1
#transferMoney ()方法实现用户向其它银行卡转账的功能,该方法中需先确保主卡用户和转入卡用户同时存在,再向用户提示要转入的金额进而判断
def transferMoney(self):
MasterTF = self.searchUser(base=2)
if (MasterTF == -1):
return -1
userTF = self.searchUser(base=3)
if (userTF == -1):
return -1
in_tr_Money = float(input("请输入转账金额:"))
if MasterTF.card.money >= in_tr_Money:
str = input("您确认要继续转账操作吗(y/n)?:")
if str.upper() == "Y":
MasterTF.card.money -= in_tr_Money
userTF.card.money += in_tr_Money
print("转账成功! 账户: %s 余额: %.2f " %
(MasterTF.card.cardId, MasterTF.card.money))
else:
print("转账失败,中止了操作")
else:
print("转账失败,余额不足! 账户: %s 余额: %.2f " %
(MasterTF.card.cardId, MasterTF.card.money))
#unlockCard ()方法实现解锁银行卡的功能
def unlockCard(self):
inptcardId = input("请输入您的卡号:")
user = self.alluser.get(inptcardId)
while 1:
if not self.alluser.get(inptcardId):
print("此卡号不存在...解锁失败!")
return -1
elif not user.card.cardLock:
print("该卡未被锁定,无需解锁!")
break
elif not self.checkpwg(user.card.cardPwd):
print("密码错误...解锁失败!!")
return -1
user.card.cardLock = False # 解锁
print("该卡 解锁 成功!")
break
class Card:
def __init__(self,cardId,cardPwd,money):
self.cardId = cardId
self.cardPwd = cardPwd
self.money = money
self.cardLock = False
class User:
def __init__(self, name, id, phone, card):
self.name = name
self.id = id
self.phone = phone
self.card = card
from admin import Admin
from atm import ATM
import time
class HomePage:
def __init__(self):
self.allUserD = {} # 使用字典存储数据
self.atm = ATM(self.allUserD)
self.admin = Admin() # 管理员开机界面
def saveUser(self):
self.allUserD.update(self.atm.alluser)
print("数据存盘成功")
# 程序的入口
def main(self):
self.admin.printAdminView()
resL = self.admin.adminOption()
if not resL:
while True:
self.admin.printsysFunctionView()
option = input("请输入您的操作:")
if option not in ("1", "2", "3", "4", "5",
"6", "7", "S", "Q", "q"):
print("输入操作项有误,请仔细确认!")
time.sleep(1)
if option == "1": # 开户
self.atm.creatUser()
elif option == "2": # 查询
self.atm.searchUser()
elif option == "3": # 取款
self.atm.getMoney()
elif option == "4": # 存储
self.atm.saveMoney()
elif option == "5": # 转账
self.atm.transferMoney()
elif option == "6": # 锁定
self.atm.lockCard()
elif option == "7": # 解锁
self.atm.unlockCard()
elif option.upper() == "Q":
if not (self.admin.adminOption()):
self.saveUser()
print('退出系统')
return -1
if __name__ == "__main__":
homepage = HomePage()
homepage.main()
运行结果:
课后编程1:设计一个Circle(圆)类,该类中包括属性radius(半径),还包括__init__()、get_perimeter()(求周长)和get_area()(求面积)共3个方法。设计完成后,创建Circle类的对象求圆的周长和面积。
class Circle:
def __init__(self,radius):
self.radius=radius
def perimeter(self):
return 3.14*2*self.radius
def get_area(self):
return 3.14*self.radius*self.radius
circle=Circle(6)
print('周长是{},面积是{}'.format(circle.perimeter(),circle.get_area()))
运行结果:
课后编程2:设计一个Course(课程)类,该类中包括number(编号)、name(名字)、teacher(任课老师)、location(上课地点)共4个属性,其中location是私有属性;还包括__init__()、show_info()(显示课程信息)共2个方法。设计完成后,创建Course类的对象显示课程的信息。
class Course:
def __init__(self, number, name, teacher, place):
self.number = number
self.name = name
self.teacher = teacher
self.__place = place
def show(self):
return '课程编号{}、课程名称{}、任课教师{}、上课地点{}'.format(self.number, self.name, self.teacher, self.__place)
a = Course(1, 'python', '张老师', '1-401')
b = Course(2, "math", "王老师", "1-4机房")
c = Course(3, "English", "刘老师", "Dingding")
print(a.show())
print(b.show())
print(c.show())
运行结果:
第9章
9.5.1 头像格式检测
我们在网站上传头像时,需要按照网站的要求上传指定格式的图片文件,若上传非指定的文件格式会出现错误的提示。例如,某网站只允许用户上传jpg、png和jpeg格式的文件,若上传其他格式的文件,则提示用户。本案例要求编写代码,通过异常捕获语句实现用户上传头像格式检测的功能。
class FileTypeError(Exception):
def __init__(self, err="仅支持jpg/png/bmp格式"):
super().__init__(err)
file_name = input("请输入上传图片的名称(包含格式):")
try:
if file_name.split(".")[1] in ["jpg", "png", "bmp"]:
print("上传成功")
else:
raise FileTypeError
except Exception as error:
print(error)
9.5.2商品与数量检测
网络购物极大地便利了我们的生活,它通过网络商城供用户选购商品,采用快递的形式送货上门。用户在进行网购时,需要同时选择商品及数量,只有输入的商品数量不小于1才符合规则,小于1则提示错误信息并设为默认值1。本案例要求编写代码,实现具有检测商品数量是否符合规则的程序。
程序运行如下图所示。
"""
xx 超市
选购
如果数量输入为负数则触发自定义异常
"""
class QuantityError(Exception):
def __init__(self, err="输入无效"):
super().__init__(err)
li = []
def shopping():
all_total = 0
goods_dict = {"五常大米": 45.00, "五丰河粉": 29.90, "农家大米": 45.00, "纯香香油": 22.90}
print('名称 价格')
print('按q退出')
for name,price in goods_dict.items():
print(f"{name} {price}¥")
while True:
# 购物车列表
cart_dict = {}
# 商品名称
goods_name = input("请输入选购的商品名称:\n")
if goods_name =='q':
break
# 商品数量
else:
try:
goods_num = int(input("请输入选购的数量:\n"))
cart_dict['名称'] = goods_name
cart_dict['数量'] = goods_num
li.append(cart_dict)
if goods_num<0:
raise QuantityError
except QuantityError as error:
print(error)
print("商品数量默认为1")
cart_dict['数量'] = 1
judge = input("是否修改商品数量:Y or N:\n")
if judge =='Y'or'y':
new_goods_num = int(input("请输入商品数量:"))
cart_dict['数量'] = new_goods_num
else:
cart_dict['数量'] = 1
for i in li:
total = goods_dict[i['名称']] * i['数量']
all_total += total
print(f'总消费{all_total}元')
if __name__ == '__main__':
shopping()
运行结果:
课后习题1:编写程序,按用户输入的半径计算圆的面积,若半径为负值则抛出异常。
r = float(input('请输入圆的半径:'))
if r >= 0:
s = 3.14 * r * r
print(s)
else:
raise (Exception)
运行结果:
课后练习2:编写程序,按用户输入的三角形3条边判断能否构成直角三角形,若能构成则计算三角形的面积和周长,否则引发异常。
import math
a,b,c = eval(input('请输入三条边长(用逗号隔开):'))
if a+b>c and a+c>b and b+c>a:
s = 1/2*(a+b+c)
mji = math.sqrt(s*(s-a)*(s-b)*(s-c))
zouc = a+b+c
print('面积:%.2f,周长:%.2f' %(mji, zouc))
else:
raise (Exception)
运行结果:
第10章
10.4.1 图形绘制
本案例要求编写程序,在程序中利用turtle模块绘制几何图形,效果如下图所示。
import turtle#引入库,创建图形窗口
# 三角形
turtle.pensize(3)
# 抬起画笔
turtle.penup()
# 移动到指定位置
turtle.goto(-200, -50)
# 放下画笔
turtle.pendown()
# 开始填充
turtle.begin_fill()
# 填充颜色
turtle.color('red')
# 半径为40
turtle.circle(40, steps=3)
# 填充结束
turtle.end_fill()
# 正方形
turtle.penup()
turtle.goto(-100, -50)
turtle.pendown()
turtle.begin_fill()
turtle.color('blue')#设置填充颜色
turtle.circle(40, steps=4)#steps设置步长
turtle.end_fill()
# 五边形
turtle.penup()
turtle.goto((0, -50))
turtle.pendown()
turtle.begin_fill()
turtle.color('yellow')
turtle.circle(40, steps=5)
turtle.end_fill()
# 六边形
turtle.penup()
turtle.goto(100, -50)
turtle.pendown()
turtle.begin_fill()
turtle.color('seashell')
turtle.circle(40, steps=6)
turtle.end_fill()
# 圆形
turtle.penup()
turtle.goto(200, -50)
turtle.pendown()
turtle.begin_fill()
turtle.color('purple')
turtle.circle(40)
turtle.end_fill()
# 文字
turtle.color('green')
turtle.penup()
turtle.goto(-100, 50)
turtle.pendown()
turtle.write("Cool Colorful Shapes", font=("Times", 18, "bold"))
# 可见性,隐藏海龟,也就是海龟画笔
turtle.hideturtle()
turtle.done()
运行结果:
10.4.2 模拟时钟
钟表是一种计时的装置,也是计量和指示时间的精密仪器。钟表的样式千变万化,但是用来显示时间的表盘相差无几,大多数钟表表盘的样式由刻度(共60个,围成圆形)、指针(时针、分针和秒针)、周日期显示和日期显示组成,如下图所示。
import turtle
from datetime import datetime
def skip(step):
'''
将画笔移动到指定的距离
'''
turtle.penup()
turtle.forward(step)
turtle.pendown()
def setup_clock(radius):
'''
建立钟表的外框
'''
turtle.reset()
turtle.pensize(7) # 设置画笔线条的粗细
for i in range(60):
skip(radius) # 在距离圆心为r的位置落笔
if i%5==0: # 若能整除5,则画一条短直线
turtle.forward(20)
skip(-radius-20)
else: # 否则画点
turtle.dot(5)
skip(-radius)
turtle.right(6)
def make_hand(name,length):
'''
注册turtle形状,建立名字为name的形状
'''
turtle.reset()
skip(-0.1*length)
# 开始记录多边形的顶点
turtle.begin_poly()
turtle.forward(1.1*length)
# 停止记录多边形的顶点,并与第一个顶点相连
turtle.end_poly()
# 返回最后记录的多边形
handForm=turtle.get_poly()
# 注册形状,命名为name
turtle.register_shape(name,handForm)
def init():
global secHand, minHand, hurHand, printer
# 重置turtle指针向北
turtle.mode("logo")
# 建立三个表针Turtle并初始化
secHand=turtle.Turtle()
make_hand("secHand", 125) # 秒针
secHand.shape("secHand")
minHand=turtle.Turtle()
make_hand("minHand", 130) # 分针
minHand.shape("minHand")
hurHand=turtle.Turtle()
make_hand("hurHand", 90) # 时针
hurHand.shape("hurHand")
for hand in secHand, minHand, hurHand:
hand.shapesize(1,1,3) # 调整三根指针的粗细
hand.speed(0) # 设置移动速度
# 建立并输出文字的turtle对象
printer=turtle.Turtle()
printer.hideturtle()
printer.penup()
def week(t):
week=["星期一","星期二","星期三","星期四","星期五","星期六","星期七"]
return week[t.weekday()]
def day(t):
return "%s %d %d" %(t.year,t.month,t.day)
def tick():
'''
绘制钟表的动态显示
'''
t=datetime.today()
second=t.second+t.microsecond*0.000001
minute=t.minute+t.second/60.0
hour=t.hour+t.minute/60.0
# 将画笔的方向设置为to_angle参数
secHand.setheading(second*6)
minHand.setheading(minute*6)
hurHand.setheading(hour*30)
turtle.tracer(False)
printer.fd(70) # 向前移动指定的距离
# 根据对齐(“左”,“中”或右“)和给定字体,在当前龟位置写入文本
printer.write(week(t),align="center",font=("Courier", 14, "bold"))
printer.back(130)
printer.write(day(t),align="center",font=("Courier", 14, "bold"))
# 将位置和方向恢复到初始状态,位置初始坐标为(0,0),
# 方向初始为:"standard"模式为right向右即东,"logo"模式是up向上即北
printer.home()
turtle.tracer(True)
turtle.ontimer(tick,100)# 计时器,100ms后继续调用tick
def main():
# 关闭绘画追踪,可以用于加速绘画复杂图形
turtle.tracer(False)
init()
# 画表框
setup_clock(200)
# 开启动画
turtle.tracer(True)
tick()
# 启动事件循环,开始接收鼠标的和键盘的操作
turtle.done()
main()
运行结果:
10.6.1 出场人物统计
《西游记》是中国古代第一部浪漫主义章回体长篇神魔小说,是中国古典四大名著之一。全书主要描写了孙悟空出世及大闹天宫后,与唐僧、猪八戒、沙悟净和白龙马四人一同西行取经,历经九九八十一难到达西天见到如来佛祖,最终五圣成真的故事。《西游记》篇幅巨大、出场人物繁多,本案例要求编写程序,统计《西游记》小说中的关键人物的出场次数。
涉及到TXT文件,可以自行编写
import jieba
# 打开并读取“西游记.txt”
txt = open(r"西游记.txt", "rb").read()
# 构建排除词库
excludes = {"一个", "那里", "怎么", "我们", "不知", "两个", "甚么",
"只见", "不是","原来", "不敢", "闻言", "如何", "什么"}
# 使用jieba分词
words = jieba.lcut(txt)
# 对划分的单词计数
counts = {}
for word in words:
if len(word) == 1:
continue
elif word == "行者" or word == "大圣" or word == "老孙":
rword = "悟空"
elif word == "师父" or word == "三藏" or word == "长老":
rword = "唐僧"
elif word == "悟净" or word == "沙和尚":
rword = "沙僧"
else:
rword = word
counts[rword] = counts.get(rword, 0) + 1
# 删除无意义的词语
for word in excludes:
del counts[word]
# 按词语出现的次数排序
items = list(counts.items())
items.sort(key=lambda x: x[1], reverse=True)
# 采用固定的格式进行输出
for i in range(9):
word, count = items[i]
print("{0:<5}{1:>5}次".format(word, count))
运行结果:
10.6.2 小猴子接香蕉
小猴子接香蕉游戏是一个根据游戏得分判定玩家反应力的游戏,该游戏的设定非常简单,游戏主体为香蕉和猴子:香蕉从屏幕顶端随机位置出现,垂直落下,玩家用鼠标左右键控制猴子左右移动,接住下落的香蕉,猴子每接到一个香蕉加10分。
本实例要求编写程序,实现一个小猴子接香蕉游戏。
import random
from sys import exit
import pygame
from pygame.locals import *
pygame.init()
# 屏幕宽度
screen_width = 450
# 屏幕高度
screen_height = 560
# 绘制窗口
screen = pygame.display.set_mode((screen_width, screen_height), 0, 32)
# 游戏标题
pygame.display.set_caption("猴子接桃")
# 分数字体,字号
run_time_font = pygame.font.SysFont('simhei', 48)
def game_start():
# 加载图片
monkey = pygame.image.load('monkey.png')
banana = pygame.image.load('banana.png')
game_background = pygame.image.load('background.jpg')
# 香蕉下落速度
speed = 1
# 分数
score = 0
# 猴子位置信息
monkey_x = 200
monkey_y = 470
# 设置移动速度
monkey_x_speed = 1
monkey_move = {K_LEFT: 0, K_RIGHT: 0}
# 香蕉坐标列表
pos_list = []
# 绘制初始化香蕉
for i in range(7):
x = random.randint(0, 390)
y = random.randint(0, 560)
pos_list.append([x, y])
# 帧率控制Clock对象
clock = pygame.time.Clock()
while True:
screen.blit(game_background, (0, 0))
# 接收信息处理
for event in pygame.event.get():
if event.type == QUIT:
exit()
if event.type == KEYDOWN:
if event.key in monkey_move:
monkey_move[event.key] = 1
elif event.type == KEYUP:
if event.key in monkey_move:
monkey_move[event.key] = 0
second_time_passed = clock.tick(60)
# 定位猴子移动后坐标
monkey_x -= monkey_move[K_LEFT] * monkey_x_speed * second_time_passed
monkey_x += monkey_move[K_RIGHT] * monkey_x_speed * second_time_passed
# 判断猴子边界条件
if monkey_x > 450 - monkey.get_width():
monkey_x = 450 - monkey.get_width()
elif monkey_x < 0:
monkey_x = 0
screen.blit(monkey, (monkey_x, monkey_y))
for y in pos_list: # 坐标循环,从y轴垂直下落
y[1] = y[1] + speed
screen.blit(banana, (y[0], y[1])) # 绘制香蕉
if y[1] >= 560:
y[1] = -banana.get_height()
# 碰撞检测
if monkey_x < y[0] < monkey_x + monkey.get_width() and monkey_y - banana.get_height() < y[1] < monkey_y:
score += 10
pos_list.remove([y[0], y[1]])
x, y = random.randint(0, 390), random.randint(0, 560)
if len(pos_list) <= 6:
pos_list.append([x, -y])
screen_score = run_time_font.render('分数:' + str(score), True, (255, 0, 0))
screen.blit(screen_score, (0, 0))
# 刷新显示
pygame.display.update()
if __name__ == '__main__':
while True:
game_start()
运行结果:
文章出处登录后可见!