前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python——三级菜单(字典+文件读写)

Python——三级菜单(字典+文件读写)

作者头像
Ed_Frey
发布2019-07-04 14:28:15
1.3K0
发布2019-07-04 14:28:15
举报
文章被收录于专栏:奔跑的键盘侠奔跑的键盘侠

三级菜单,按省、市、县三级做一个查询菜单,要求如下,

代码语言:javascript
复制
1.可逐级查询(比如输入山东省,跳出山东所有市,再输入青岛市,可展示青岛所有县)
2.输入b可以返回上一层,比如莱西一级,输入b返回上级青岛,再输入b返回山东。
3.输入q退出。
代码语言:javascript
复制
这个是上上期的三级菜单的题目。
后来呢,又学了文件读写的章节,然后题目又延伸了一下,延伸内容如下:
代码语言:javascript
复制
代码语言:javascript
复制
1.将三级菜单存入文本文件中
2.展示省市县,数据存在文本中;
3.对菜单实现增删改,删、改容易理解,增么,就是用户增加一个城市

第3条中的增乍一看挺简单,琢磨一下,要处理文本,还有编码貌似挺复杂的。不对,如果要删中间级咋整?这是一个坑啊,中间级必须先删光子级才允许删。。目前依旧是按照刚入门的基本语法来完成这个题目,这题目不难,但是写起来挺坑的,愣是写了100多行……
代码语言:javascript
复制
前两天的代码果然有问题,网上翻了一下,主要问题吧,是干了一件傻事,字典的增删改差,愣是被我做成了文本的增删改查。所以删减了三十行代码,现在看起来好了那么一点点。
代码中的district_database文档,就是txt文档,内容如下
代码语言:javascript
复制
{
    '1001':'北京市',
    '100101':'北京市辖区',
    '10010101':'东城区',
    '10010102':'西城区',
    '10010103':'朝阳区',
    '100102':'北京市县',
    '10010201':'密云县',
    '10010202':'延庆县',
    '1002':'天津市',
    '100201':'天津市辖区',
    '10020102':'和平区',
    '10020103':'河东区',
    '10020104':'河西区',
    '10020105':'南开区',
    '10020106':'河北区',
    '100202':'天津市县',
    '10020203':'宁河县',
    '10020201':'静海县',
    '10020202':'蓟县',
    }
代码语言:javascript
复制
代码语言:javascript
复制
#!/usr/bin/env python3.6
# -*- coding: utf-8 -*-
#__author__:  Ed Frey
#Date: 18/8/2

current_layer_len = 4  #第一层省份编码长度是4位数
parent_layer = '10'   #父层编码初始值取编码前2位,也就是10.  输入下一级城市时,城市编码增加2位,父层编码就是切片城市编码[:-2]

with open('district_database', 'r') as f:
    menu = f.read()
menu = eval(menu)

while True:
    current_layer = {key:value for key,value in menu.items() if len(key) == current_layer_len and key.startswith(parent_layer)}
    #取出相应位数编码的城市。
    print('The current layer of cities:')
    for i in current_layer:
        print(current_layer[i])
    choice = input('Please input the district(press b/q/d/c/a to back or quit or delete or change or append):').strip()
    if len(choice) == 0:continue
    if choice in current_layer.values():
        parent_layer = list(current_layer.keys())[list(current_layer.values()).index(choice)]
        # print(parent_layer) 字典无序,转换成列表,然后根据输入的城市的序号,获取当前城市的编码
        current_layer_len += 2
    elif choice == 'b':#返回上一层
        if current_layer_len-2:
            current_layer_len -= 2
            parent_layer = parent_layer[:-2]
    elif choice == 'd':#删除当前城市(如有下级一并删除)
        choice2=input('Please input the city you want to delete:'.strip())
        if choice2 in current_layer.values():
            for key in menu:
                if menu[key] == choice2:
                    sub_code=key
                    break
            sub_code2=[]
            for key in menu:
                if key.startswith(sub_code):
                    sub_code2.append(key) 
                    #如果要删的城市有子集,要全部删掉,比如要删1002天津,那就把1002开头的所有下级城市,一并删除,那也就是要汇集这些城市的序号。
            for code in sub_code2:
                del menu[code]
            continue
        else:
            print('invalid input!!!')
    elif choice == 'c':#修改当前城市名称
        choice2 = input('Please input the city you want to change:'.strip())
        if choice2 in current_layer.values():
            choice3 = input('Please input the result:'.strip())
            for key in menu:
                if menu[key] == choice2:
                    sub_code=key
                    break
            menu[sub_code]=choice3
            continue
        else:
            print('invalid input!!!')
    elif choice == 'a':#增加新城市
        choice2 = input('Please input the city you want to append current layer:'.strip())
        if choice2 in current_layer.values():
            print(f'{choice2} exists!!!')
        else:
            append_max_code = 0
            for sub_code in current_layer:
                if int(sub_code) > append_max_code:
                    append_max_code = int(sub_code) # 取当前层城市编码最大值
            append_max_code += 1
            #要增加一个新城市,同样,要编一个序号,取该级别下的最大序号,再加1,作为新城市的序号。
            menu[str(append_max_code)]=choice2
            continue
    elif choice == 'q':#退出并存盘数据。
        with open('district_database', 'w') as f:
            f.write(str(menu))# 按q退出时,再将最终结果写入文本中。
代码语言:javascript
复制
        break
代码语言:javascript
复制
    else:
        print('invalid input,try again please')
        
那网上大神的代码也贴一下供大家参考:
链接https://www.cnblogs.com/Yongzyw/p/8654746.html

代码语言:javascript
复制
#初始化 将menu存入磁盘中
# menu = {'北京':{
#     '朝阳':{
#         '国贸':{
#             'CICC':{},
#             'HP':{},
#             '渣打银行':{},
#             'CCTV':{}
#         },
#         '望京':{
#             '陌陌':{},
#             '奔驰':{},
#             '360':{}
#         },
#         '三里屯':{
#             '优衣库':{},
#             'apple':{}
#         }
#     },
#     '昌平':{
#         '沙河':{
#             '老男孩':{},
#             '阿泰包子':{}
#         },
#         '天通苑':{
#             '链家':{},
#             '我爱我家':{}
#         },
#         '回龙观':{}
#     },
#     '海淀':{
#         '五道口':{
#             '谷歌':{},
#             '网易':{},
#             'Souhu':{},
#             'Sogo':{},
#             '快手':{}
#         },
#         '中关村':{
#             'youku':{},
#             'Iqiyi':{},
#             '汽车之家':{},
#             '新东方':{}
#         }
#     }
# },
#         '上海':{
#             '浦东':{
#                 '陆家嘴':{
#                     'CICC':{},
#                     '高盛':{},
#                     '摩根':{}
#                 },
#                 '外滩':{}
#             },
#             '闵行':{},
#             '静安':{}
#         },
#         '山东':{
#             '济南':{},
#             '德州':{
#                 '乐陵':{
#                     '丁务镇':{},
#                     '城区':{}
#                 },
#                 '平原':{}
#             },
#             '青岛':{}
#         }
# }
# a=str(menu)
# with open('menu','w',encoding='utf8') as f:
#     f.write(a)
#读取menu
with open('menu','r',encoding='utf8') as f:
    menu=eval(f.read().strip())
parent_layers=[]
current_layer = menu
while True:
    print('欢迎使用省市查询系统'.center(50,'*'))
    for key in current_layer:
        print('>>>',key)
    print('输入你要查询的地区省市或新增[add]、修改[revise]、删除[delete]、返回上一级[q]')
    choice = input('>>>').strip()
    #查询
    if choice in current_layer:
        parent_layers.append(current_layer)
        current_layer = current_layer[choice]
    #新增
    elif choice == 'add':
        user_add = input('请输入你要添加的省市区:').strip()
        if user_add in current_layer:
            print('此项已存在,请重新输入')
        else:
            current_layer[user_add]={}
            continue
    #修改
    elif choice =='revise':
        user_revise = input('请输入要修改的省市区:').strip()
        if user_revise in current_layer:
            user_revise_after = input('修改为:').strip()
            current_layer[user_revise_after]=current_layer[user_revise]
            del current_layer[user_revise]
            continue
    #删除
    elif choice =='delete':
        user_delete = input('请你输入要删除的省市区:').strip()
        if user_delete in current_layer:
            parent_layers.append(current_layer)
            del current_layer[user_delete]
            continue
        else:
            print('此项不存在,请重新输入:')
    #返回上一级或退出
    elif choice == 'q':
        if parent_layers:
            current_layer = parent_layers.pop()
        else:
            print('目前为最上级菜单,输入q后为退出系统!')
            print(type(current_layer))
            break
    else:
        print('输入非法,请重新输入选择!')
if type(current_layer) != list:
    with open('menu','w',encoding='utf8') as f:
        f.write(str(current_layer))

写的很完美,对不对?慢慢来,不急躁。向大神学习。

不过,我个人觉得数据写入这个节点,还是放到代码中间,修改完立即写入比较好。毕竟遇到非正常情况退出,那修改内容就丢失了。另外关于删除城市,有下一级的也全部删除,欠妥,应该提示有子城市,须逐级删。不过真要细化下去,就有得写了。

另外总觉得这节课都是在讲解文本的各种方法,然后布置的这个作业,跟文件的n多方法有多大关联?就一个读一个写?文本处理都没涉及,走歪了也不能全怪我咯

关于字典和文件的章节,暂时告一段落了。

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-08-04,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 奔跑的键盘侠 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档