目录
十八、思维课-用编程能力解决实际问题
实战=编程基础知识+生活经验+产品思维
“产品”——为自己或他人服务的程序
“思维”——设计产品的思考方式
流程图
产品设计
如何提需求
如何设计解决方案
eg.制作一个自动统计考勤表数据并输出结果的程序。
练习
(1)“不知道吃什么”
目标:电脑推荐我们吃某种菜,我们拒绝后,它就继续推荐,直到我们满意为止。
所用知识:
判断: 判断语句+input
随机推荐:random模块+循环+判断
特定选项的随机选项:列表添加+random模块+循环+判断
import random
choice1 = ['小龙虾自助','麻辣烫','花市豌杂面','广州强记早茶','高胖妹重庆小面']
choice2 = ['红烧肉','炸鸡腿','炸鱼薯条','咖喱鱼蛋']
list = [choice1,choice2]
print('以下是各大美食区up主做过/吃过的美食,你看一下哪些是你想吃的')
while True:
a = random.choice(list)
print(a)
sentence = input('你看这一栏是你喜欢吃的吗\n')
if sentence == '是':
break
for i in a :
print(i)
b= int(input('你想要第几种啊\n'))
print(a[b-1])
(2)滚动的广告牌
目标:模拟有单行滚动字体的广告牌
所用知识:
滚动效果:os模块cls清屏+print+将字符串中第一个元素移到最后一个+循环
控制滚动速度:time模块sleep
import os, time
def main(): # 用函数封装,可复用性会高一些
content = ' 关注公众号“瑶学英语”,陪你看最新的《经济学人》! '
while True:
os.system('cls')
print(content)
content = content[1:] + content[0]
time.sleep(1)
if __name__ == '__main__': # 类里面学到的检测方法,在函数中其实也可以用。
main()
十九、
目标
把一个小区某一栋楼内的所有户室的资料录入到excel表里,这栋楼的资料是这样子的:
流程图
阶段1.0:输入固定表头,确定模板数据
如果你用的是Mac电脑,当你直接用excel打开csv文件可能会显示乱码,这是因为Mac电脑打开excel是默认用GBK编码处理中文的,而Python默认是UTF-8编码,所以导致加载出来是乱码。
解决方案是Mac用户要在open()函数里加上参数'encoding='GBK'。
import csv
with open('assets.csv','a',newline='') as csv.file:
writer = csv.writer(csvfile, dislect='excel')
header = ['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积']
writer.writerow(header)
#先考虑可以重复使用的数据
title = input('请输入小区名称')
address = input('请输入小区地址:')
year = input('请输入小区建造年份:')
block = input('请输入楼栋号:')
阶段2.0:获取模板数据,复用模板数据
同一单元下,每一楼的户型和朝向一般是一样的,也就是只需要知道一个单元下某一楼层的数据,该单元的其它楼层都可以复用,区别只是户室号。
户室号一般是由楼层+后两位序号(以下我会简称为尾号)组成的,如201,202,203,204;301,302,303,304...尾号是统一的,变的只是前面的楼层数(每层加一),所以户室号拆成两部分处理会方便我们后续的操作。
现在我们需要拿到的是起始楼层每一个户室的朝向和面积,我们可以判断出朝向和面积是并列关系,它是从属于户室的。我们很自然能想到这里用字典嵌套列表的形式会更方便,其中字典的键是户室号,面积和朝向组成的列表为字典的值。
start_floor = input('请输入起始楼层:')
end_floor = input('请输入终止楼层:')
input('接下来请依次输入起始层每个房间的户室尾号、南北朝向及面积,按任意键继续')
start_floor_rooms = {}
floor_last_number = []
# 收集起始层的房间信息
# 定义循环控制量
room_loop = True
while room_loop:
last_number = input('请输入起始楼层户室的尾号:(如01,02)')
floor_last_number.append(last_number)
#将尾号用append()添加列表里,如floor_last_number = ['01','02']
room_number = int(start_floor + last_number)
#户室号为room_number,由楼层start_floor和尾号last_number组成,如301
direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number ))
area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number))
start_floor_rooms[room_number] = [direction,area]
# 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]}
continued= input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续:')
#加入打破循环的条件
if continued == 'n':
room_loop = False
else:
room_loop = True
print(start_floor_rooms)
现在,我们就获得了一个存储了某一单元起始楼层所有户室信息的字典。那怎么迁移呢?我们的第一反应可能是给每一个楼层都创建一个新字典,这样虽然可行,但随着楼层的增加,字典就会有非常多个,不好管理, 所以把一个单元内所有楼层的数据放在一块会更方便我们的处理,也就是说将每一个楼层的字典统一放在一个存放单元级的字典里。
unit_rooms={ 3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}, 4:{401:[1,80],402:[1,80],403:[2,90],404:[2,90]}, 5:{501:[1,80],502:[1,80],503:[2,90],504:[2,90]} }
start_floor = input('请输入起始楼层:')
end_floor = input('请输入终止楼层:')
floor_last_number = ['01','02','03']
start_floor_rooms = {301:[1,80],302:[1,80],303:[2,90]}
#初始楼层的模版数据
unit_rooms = {}
#新建一个存放所有楼层的字典
unit_rooms[int(start_floor)] = start_floor_rooms
for floor in range(int(start_floor) + 1, int(end_floor) + 1):
#遍历除初始楼层外的其他楼层
floor_rooms = {}
#每个楼层都建立一个字典
for i in range(len(start_floor_rooms)):
#遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环
number = str(floor) + floor_last_number[i]
info = start_floor_rooms[int(start_floor + floor_last_number[i])]
# 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表
floor_rooms[int(number)] = info
#给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]}
unit_rooms[floor] = floor_rooms
print(unit_rooms)
阶段3.0:写入csv文件,单元间循环
在阶段2.0,我们把一个单元内所有户室的数据都存在unit_rooms这个字典里,理论上我们已经可以以单元为单位写入到csv文件,现在最关键的是如何从字典取出我们想要的数据。
大字典的值是小字典(sub_dict),其中户室是大字典的键,朝向是小字典的值(列表)的第0个元素,面积是小字典的值(列表)的第1个元素。 也就是说我们需要的数据都在大字典的值里,所以第一步我们需要遍历大字典里的键(key),来取出值(value)。
for value in DictName.values(): # value的名字可以自行另取 # DictName是要遍历的字典的名称 # .values():是固定的用法
前面我们分析过户室号是sub_dict的键,朝向和面积是sub_dict的值,所以下一步就是要遍历sub_dict的键和值。
for k,v in DictName.items(): #遍历字典的键值对,k对应键,v对应值 #k,v 的名字可以自己取,DictName是字典名
还有个细节是一开始我们将'南北'记成1,'东西'记成2,所以现在我们需要改回来。事实上我们用条件判断和赋值语句就可以了。
for sub_dict in unit_rooms.values():
for room,info in sub_dict.items():
if info[0] == 1:
info[0] = '南北'
elif info[0] == 2:
info[0] = '东西'
另外一种方法,是对列表索引的活用
for sub_dict in unit_rooms.values():
for room,info in sub_dict.items():
dire = ['', '南北', '东西']
#建立一个列表,第0个元素为空,第1个元素为'南北',第2个元素为'东西'
print(dire[info[0]])
info[0]的值不是1就是2,所以dire[info[0]]不是dire[1]就是dire[2]。 如果是dire[1],就是取列表dire的第一个元素'南北',dire[2]则取'东西'。
成果展示
import csv
#调用csv模块
with open('assets.csv', 'a', newline='') as csvfile:
#调用open()函数打开csv文件,传入参数:文件名“assets.csv”、追加模式“a”、newline=''。
writer = csv.writer(csvfile, dialect='excel')
# 用csv.writer()函数创建一个writer对象。
header=['小区名称', '地址', '建筑年份', '楼栋', '单元', '户室', '朝向', '面积']
writer.writerow(header)
title=input('请输入小区名称:')
address = input('请输入小区地址:')
year = input('请输入小区建造年份:')
block = input('请输入楼栋号:')
unit_loop = True
while unit_loop:
unit=input('请输入单元号:')
start_floor = input('请输入起始楼层:')
end_floor = input('请输入终止楼层:')
# 开始输入模板数据
input('接下来请输入起始层每个房间的门牌号、南北朝向及面积,按任意键继续')
start_floor_rooms = {}
floor_last_number = []
# 收集起始层的房间信息
# 定义循环控制量
room_loop = True
while room_loop:
last_number = input('请输入起始楼层户室的尾号:(如01,02)')
floor_last_number.append(last_number)
#将尾号用append()添加列表里,如floor_last_number = ['01','02']
room_number = int(start_floor + last_number)
#户室号为room_number,由楼层start_floor和尾号last_number组成,如301
direction = int(input('请输入 %d 的朝向(南北朝向输入1,东西朝向输入2):' % room_number ))
area = int(input('请输入 %d 的面积,单位 ㎡ :' % room_number))
start_floor_rooms[room_number] = [direction,area]
# 户室号为键,朝向和面积组成的列表为值,添加到字典里,如start_floor_rooms = {301:[1,70]}
continued= input('是否需要输入下一个尾号?按 n 停止输入,按其他任意键继续:')
#加入打破循环的条件
if continued == 'n':
room_loop = False
else:
room_loop = True
unit_rooms = {}
#新建一个放单元所有户室数据的字典
unit_rooms[start_floor] = start_floor_rooms
#unit_rooms={3:{301:[1,80],302:[1,80],303:[2,90],304:[2,90]}}
for floor in range(int(start_floor) + 1, int(end_floor) + 1):
#遍历除初始楼层外的其他楼层
floor_rooms = {}
#每个楼层都建立一个字典
for i in range(len(start_floor_rooms)):
#遍历每层有多少个房间,这里是3,即执行for i in range 3 的循环
number = str(floor) + floor_last_number[i]
info = start_floor_rooms[int(start_floor + floor_last_number[i])]
# 依次取出字典start_floor_rooms键对应的值,即面积和朝向组成的列表
floor_rooms[int(number)] = info
#给字典floor_rooms添加键值对,floor_rooms = {401:[1,80]}
unit_rooms[floor] = floor_rooms
with open('assets.csv', 'a', newline='')as csvfile:
#Mac用户要加多一个参数 encoding = 'GBK'
writer = csv.writer(csvfile, dialect='excel')
for sub_dict in unit_rooms.values():
for room,info in sub_dict.items():
dire = ['', '南北', '东西']
writer.writerow([title,address,year,block,unit,room,dire[info[0]],info[1]])
unit_continue = input('是否需要输入下一个单元?按 n 停止单元输入,按其他任意键继续:')
if unit_continue == 'n':
unit_loop = False
else:
unit_loop = True
print('恭喜你,资产录入工作完成!')
练习-新年时面对亲戚的话术训练
练习目标: 写一个测试程序,测一测你的朋友在面对亲戚好友的“关心”时,是否能顺利接招。
练习要求: 提示本测试的背景信息; 写入选择题,让好友根据自己的情况选出答案; 计算选项得分,最终判断好友测试结果 根据得分,提示该好友的话题应对灵敏度;
结构:
(1)导入模块
requests(requests网络请求库)、 json(json格式)、random(随机库)用于产生随机数
(2)导入选择题
判断本地是否有 new_year_questions.json 文件,该文件为测试用的选择题;如果存在,则读取本地文件中的内容;若没有,则利用requests的get方法获取。
(3)设置计分器
选择题一共有四个选项,请使用字典的方式设置积分器。
(4)提示测试的背景信息,并且开始提问
(5)统计选项得分,判断测试结果
测试结果使用叠加型计数方式,哪一类型选项选择次数最多,则提示该类型结果;当出现最高分同分时,则随机出现结果。
(6)把程序提交到接口
如果使用对象没有运行环境,还是无法使用你所写的程序。 这里我们需要用到web网站的技术,把你写的问答做成一个可以在微信中使用的网站。(但是还没学!)
#导入模块
import requests
import json
import random
import time
words='''今天就是除夕啦,我们都老了一岁~
为了帮大家应对七大姑八大姨的 '灵魂拷问' ~ ,模拟可能会面对的一些状况:
可以根据题目选出自己认为合适的选项~
完成题目,即可得出你应对灵魂“拷问”的灵敏度。'''
for i in words:
print(i,end='')
time.sleep(0.1)
print('下面是尬聊(避坑)指南~~')
time.sleep(1)
print('------------------------------------话题开始---------------------------------------')
time.sleep(1)
#导入选择题
try:
with open('./new_year_questions.json', encoding='utf-8') as file:
questions_json = json.loads(file.read())
except FileNotFoundError:
res = requests.get('https://static.pandateacher.com/new_year_questions.json')
with open('./new_year_questions.json', 'w', encoding='utf-8') as file:
file.write(res.text)
questions_json = res.json()
except Exception as e:
print("加载题目失败,失败原因:{}".format(e))
exit()
questions_list = questions_json['questions_list']
result = questions_json['result']
#设置计分器
point = {1:0,2:0,3:0,4:0}
num=1
#提示测试的背景信息,并且开始提问
for k in questions_list:
print(str(num)+'. 背景:'+k['q'])
time.sleep(1)
for i,answer in enumerate(k['a']):
print('(%d)%s'%(i+1, answer['desc']))
time.sleep(1)
while True:
try:
choice=int(input('你的回答是(1/2/3/4):'))
if not 1 <= choice <= 4:
raise Exception
else:
point[choice]=point[choice]+1
break
except:
x=input('输入不是答案序号(1-4),请重新输入~\n结束请按enter:')
if x=='':
exit()
else:
continue
num=num+1
print('\n--------------------------------------------------------------------------------')
time.sleep(1)
#统计选项得分
print('结果运算中...')
time.sleep(1)
max_key = 1
max_val = 0
for key,val in point.items():
print('('+str(key)+')选项,你选了'+str(val)+'次')
if val == max_val:
max_key = random.choice([key,max_key])
elif val > max_val:
max_key=key
max_val=val
else:
pass
final=result[str(max_key)]
r1=final[0]['topic']
print('猪年气质:%s\n话题表现:%s'%(final[0]['topic'],final[0]['performance']))
time.sleep(1)
print('Wish you clear and fearless. Happy New Year!')
#把程序提交到接口
jwt = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhcHAiOiJweWNsYXNzIiwiZXhwIjoxNTQ5NjExNzg5LCJpZCI6NDI2MzU5LCJvaWQiOiJvUmI4T3dnSlo3UjhraExpWEtsTzVOVklldFMwIiwicGF0aCI6Ii8iLCJwdWlkIjoiMTg5MGZlODEtNTI5NS00ZDE5LThlMmItNzc2ZTA0OTZhN2VkIiwic2NlbmUiOiJwY19zY2FuIiwic3ViIjoibzdoTEgwemc4VGxjQnpCNGVtNEpUbHRrdThObyJ9.g4UoftsqN6gIVDstgWfOfMj0mAyEv7Y-A4iFdipZtwQ'
url = 'https://www.pypypy.cn/python-class-fos/api-academy-go/spring-activity/json-data'
headers = {'Authorization': 'Bearer {}'.format(jwt)}
data = {'data': questions_list}
try:
res=requests.post(url, json=data, headers=headers)
res.raise_for_status()
if res.json()['errcode'] != 0:
print(res.json()['errmsg'])
print('请尝试重新运行程序!')
else:
print('提交到前端程序接口成功,点击【提交练习】后,手机扫码即可体验程序。')
except requests.exceptions.HTTPError as e:
print(e)
print('请尝试重新运行程序!')
except Exception:
print('提交到前端程序接口失败!')
print('请尝试重新运行程序!')