一、練習(xí)要求
- 從網(wǎng)上找到中國省市區(qū)的json或字典數(shù)據(jù)
- 一屋剑、二茵臭、三級菜單分別對應(yīng)省市區(qū),且每個都有單獨的代碼
- 省胧砰、市菜單有輸入對應(yīng)代碼進入下一級功能
- 有返回上一級功能和退出機制
二鳍鸵、練習(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ù)來實現(xiàn)模塊很方便,新手練習(xí)還是逐層實現(xiàn)
- 進入程序囱怕,顯示省的名字和對應(yīng)數(shù)字列表霍弹,以三列的形式來顯示
- 提示輸入省級代碼,輸入正確則進入對應(yīng)市級列表娃弓;輸入非法則提示重新輸入典格;提示輸入‘q’來退出程序(用break循環(huán))
- 市級進到縣級同上;另外忘闻,提示輸入‘r’來返回上一級
- 縣級界面钝计,提示輸入‘r’來返回上一級,‘q’來退出程序
- 設(shè)立標(biāo)志位齐佳,整體用while來循環(huán)
三私恬、代碼實現(xiàn)
- 以json方法來實現(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:
# 提示輸入省級編號進入市級,并提示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'")
-
下面是優(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ù)思考