一、練習(xí)要求
- 從網(wǎng)上找到中國省市區(qū)的json或字典數(shù)據(jù)
- 一、二、三級菜單分別對應(yīng)省市區(qū),且每個都有單獨(dú)的代碼
- 省、市菜單有輸入對應(yīng)代碼進(jìn)入下一級功能
- 有返回上一級功能和退出機(jī)制
二、練習(xí)分析
2.1 獲取源數(shù)據(jù)
全國省市區(qū)json——來源于csdb,復(fù)制數(shù)據(jù)并另存為json格式。(最好在復(fù)制后去在線json檢測網(wǎng)站檢查是否valid)
最新縣及縣以上行政區(qū)劃代碼——來源于統(tǒng)計局,復(fù)制成文本格式,后期再通過python來解析txt獲取并組成{(代碼,省):{(代碼,市):{(代碼,區(qū))}}}
直接通過統(tǒng)計局的網(wǎng)站,通過抓取來生成json文件(這個麻煩一些)
2.2 步驟分析
- 用函數(shù)來實(shí)現(xiàn)模塊很方便,新手練習(xí)還是逐層實(shí)現(xiàn)
- 進(jìn)入程序,顯示省的名字和對應(yīng)數(shù)字列表,以三列的形式來顯示
- 提示輸入省級代碼,輸入正確則進(jìn)入對應(yīng)市級列表;輸入非法則提示重新輸入;提示輸入‘q’來退出程序(用break循環(huán))
- 市級進(jìn)到縣級同上;另外,提示輸入‘r’來返回上一級
- 縣級界面,提示輸入‘r’來返回上一級,‘q’來退出程序
- 設(shè)立標(biāo)志位,整體用while來循環(huán)
三、代碼實(shí)現(xiàn)
- 以json方法來實(shí)現(xiàn)最為快捷
- json文件命名為“City_json.json ”
-
下面是版本一:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''China province to city, to district'''
__author__:'Wu HH'
# 導(dǎo)入json文件
import json
filename = 'City_json.json'
with open(filename, 'r') as file:
china_data = json.load(file)
# 打印省級的函數(shù)
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('')
# 打印市級的函數(shù)
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('')
# 打印縣級的函數(shù)
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('')
# 定位標(biāo)志
loca_num = 0
while True:
# 打印省級
if loca_num == 0:
print_pro()
loca_num = 1
if loca_num == 1:
# 提示輸入省級編號進(jìn)入市級,并提示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:
# 提示輸入市級編號進(jìn)入縣級,并提示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'")
-
下面是優(yōu)化版本二:(網(wǎng)上找的博客園-金角大王)
- 很佩服這個版本,但是交互是通過輸入完成城市名而不是數(shù)字
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'''more elegent version of China province program'''
__author__:'Wu HH'
# 導(dǎo)入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。先留著,以后有空繼續(xù)思考