美文网首页
【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