美文网首页
【python练习】中国省市区菜单

【python练习】中国省市区菜单

作者: Wuhouxxxx | 来源:发表于2017-11-11 23:28 被阅读0次

    一、练习要求

    • 从网上找到中国省市区的json或字典数据
    • 一、二、三级菜单分别对应省市区,且每个都有单独的代码
    • 省、市菜单有输入对应代码进入下一级功能
    • 有返回上一级功能和退出机制

    二、练习分析

    2.1 获取源数据

    1. 全国省市区json——来源于csdb,复制数据并另存为json格式。(最好在复制后去在线json检测网站检查是否valid)

    2. 最新县及县以上行政区划代码——来源于统计局,复制成文本格式,后期再通过python来解析txt获取并组成{(代码,省):{(代码,市):{(代码,区)}}}

    3. 直接通过统计局的网站,通过抓取来生成json文件(这个麻烦一些)

    2.2 步骤分析

    1. 用函数来实现模块很方便,新手练习还是逐层实现
    2. 进入程序,显示省的名字和对应数字列表,以三列的形式来显示
    3. 提示输入省级代码,输入正确则进入对应市级列表;输入非法则提示重新输入;提示输入‘q’来退出程序(用break循环)
    4. 市级进到县级同上;另外,提示输入‘r’来返回上一级
    5. 县级界面,提示输入‘r’来返回上一级,‘q’来退出程序
    6. 设立标志位,整体用while来循环

    三、代码实现

    • 以json方法来实现最为快捷
    • json文件命名为“City_json.json ”
    • 下面是版本一:

    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    '''China province to city, to district'''
    __author__:'Wu HH'
    
    # 导入json文件
    import json
    filename = 'City_json.json'
    with open(filename, 'r') as file:
        china_data = json.load(file)
    
    # 打印省级的函数
    def print_pro():
        count = 0
        for i in range(len(china_data)):
            count += 1
            print(china_data[i]['name'].ljust(8,'>'),'%02d'.ljust(6,' ') % i, end='')
            # 用于打印成3列
            if count % 3 == 0:
                print('')
    
    # 打印市级的函数
    def print_city(city_num):
        count = 0
        for i in range(len(china_data[city_num]['city'])):
            count += 1
            print(china_data[city_num]['city'][i]['name'].ljust(8,'>'),'%02d'.ljust(6,' ') % i, end='')
            # 用于打印成3列
            if count % 3 == 0:
                print('')
    
    # 打印县级的函数
    def print_area(city_num, area_num):
        count = 0
        for i in range(len(china_data[city_num]['city'][area_num]['area'])):
            count += 1
            print(china_data[city_num]['city'][area_num]['area'][i].ljust(8,'>'),'%02d'.ljust(6,' ') % i, end='')
            # 用于打印成3列
            if count % 3 == 0:
                print('')
    
    # 定位标志
    loca_num = 0
    
    while True:
    
        # 打印省级
        if loca_num == 0:
            print_pro()
            loca_num = 1
    
        if loca_num == 1:
            # 提示输入省级编号进入市级,并提示q退出
            into_city_num = input('Please input number to get into city. "q" to quit. ')
            if into_city_num == 'q':
                break
            elif int(into_city_num) > 0 and int(into_city_num) <= len(china_data):
                into_city_num = int(into_city_num)
                if loca_num == 1:
                    print_city(into_city_num)
                loca_num = 2
            else:
                print('please input a valid number')
    
        if loca_num == 2:
            # 提示输入市级编号进入县级,并提示q退出,r返回上一级
            into_area_num = input('Please input number to get into city. "q" to quit. "r" to return. ')
            if into_area_num == 'q':
                break
            elif into_area_num == 'r':
                loca_num = 0
                continue
            elif int(into_area_num) > 0 and int(into_area_num) <= len(china_data[into_city_num]['city']):
                into_area_num = int(into_area_num)
                if loca_num == 2:
                    print_area(into_city_num, into_area_num)
                loca_num = 3
            else:
                print('please input a valid number')
    
        if loca_num == 3:
            # 提示q退出,r返回上一级
            input_in_area = input('"q" to quit. "r" to return. ')
            if input_in_area == 'q':
                break
            elif input_in_area == 'r':
                loca_num = 2
                print_city(into_city_num)
                continue
            else:
                print("please input a 'q' or 'r'")
    
    • 下面是优化版本二:(网上找的博客园-金角大王)

    • 很佩服这个版本,但是交互是通过输入完成城市名而不是数字
    #!/usr/bin/env python3
    # -*- coding: utf-8 -*-
    
    '''more elegent version of China province program'''
    __author__:'Wu HH'
    
    # 导入json文件
    import json
    filename = 'City_json.json'
    with open(filename, 'r') as file:
        china_data = json.load(file)
    
    # 重组json成层叠字典{a:{b1:{c1:[]},c2:{}},b2:{...}...}
    china_data_dic = {}
    for province_total in china_data:
        city_temp = {}
        for city_total in province_total['city']:
            city_temp[city_total['name']] = city_total['area']
        china_data_dic[province_total['name']] = city_temp
    
    
    exit_active = False
    
    current_class = china_data_dic
    parent_classes = [china_data_dic]
    
    while not exit_active:
        count_num = 0
        for k in current_class:
            count_num += 1
            print(k.ljust(8, ' '),end='')
            if count_num % 3 == 0:
                print('')
        choice = input(">>:").strip()
        if choice == 'b' and parent_classes != []:
            current_class = parent_classes[-1]
            parent_classes.pop()
        elif choice == 'q':
            exit_active = True
        elif choice not in current_class:
            continue
        else:
            if current_class not in parent_classes:
                parent_classes.append(current_class)
            try:
                current_class = current_class[choice]
            except TypeError:
                continue
    

    思考了好一会儿都没想到怎么解决“县级在非合法输入后,需要‘b’两次才能返回市级”的bug。先留着,以后有空继续思考

    相关文章

      网友评论

          本文标题:【python练习】中国省市区菜单

          本文链接:https://www.haomeiwen.com/subject/brmwmxtx.html