Python人口数据分析程序异常求助:菜单选择逻辑问题排查
我写了个基于Python的人口数据分析小工具,原本设计是通过主菜单让用户选两个功能之一:
- 功能1:统计不同大陆的总人口
- 功能2:计算不同国家的人口变化百分比
但运行起来总有些问题,自己排查半天没头绪,贴出完整代码和样本数据,麻烦各位大佬帮忙看看!
完整代码
from collections import Counter print (30 * '-') print (" M A I N - M E N U") print (30 * '-') print ("Program 1.Total Populations of the different continents") print ("Program 2.Percentage Change(%) for different countries") print (30 * '-') Input1=1 Input2=2 ## Get input ### choice = int(input('Enter your choice [1-2] : ')) ### Take action as per selected menu-option ### while choice==1 or choice==2: if (choice == 1): counter1 = Counter() with open('a.txt') as f: for i in range(0,2): next(f) for line in f: splits = line.split(';') population = int(splits[3]) continent = splits[-1].strip() counter1[continent] += population # Print continents sorted by population for continent, pop_sum in counter1.most_common(): print(continent, ":", pop_sum) else: counter2 = Counter() with open("a.txt") as f: for i in range(0,2): next(f) for line in f: splits = line.split(';') change = float(splits[6]) country = splits[1].strip() counter2[country] += change #Percentage Change By Countries" print() print ("Percentage Change By Countries") for country, change_sum in counter2.most_common(): print(country, change_sum,"%")
样本数据(a.txt内容)
World Population Data 2019 from the United Nations
Rank; Country; 2018; 2019; % Share; Pop Change; % Change; Continent
1; China; 1427647786; 1433783686; 18.6; 6135900; 0.43; Asia
2; India; 1352642280; 1366417754; 17.7; 13775474; 1.02; Asia
3; United States of America; 327096265; 329064917; 4.27; 1968652; 0.60; North America
4; Indonesia; 267670543; 270625568; 3.51; 2955025; 1.10; Asia
5; Pakistan; 212228286; 216565318; 2.81; 4337032; 2.04; Asia
6; Brazil; 209469323; 211049527; 2.74; 1580204; 0.75; South America
7; Nigeria; 195874683; 200963599; 2.61; 5088916; 2.60; Africa
8; Bangladesh; 161376708; 163046161; 2.11; 1669453; 1.03; Asia
9; Russian Federation; 145734038; 145872256; 1.89; 138218; 0.09; Europe
10; Mexico; 126190788; 127575529; 1.65; 1384741; 1.10; North America
我总结的核心问题&修复方案
1. 最致命的循环逻辑错误
原程序的while循环条件是choice==1 or choice==2,但执行完对应功能后,没有重新获取用户输入的步骤,导致程序会无限重复执行同一个功能,完全无法回到主菜单。
2. 缺失输入验证机制
如果用户输入非整数(比如字母、符号)或者不在1-2范围内的数字,程序会直接抛出ValueError崩溃。
3. 不必要的工具使用
功能2里用Counter完全没必要——样本数据里每个国家只有一条记录,Counter是用来做累加计数的,这里只是赋值存储,用普通字典更合适。
修复后的完整代码
我调整了逻辑,解决了上述问题,还加了一些细节优化:
from collections import Counter def show_main_menu(): print(30 * '-') print(" M A I N - M E N U") print(30 * '-') print("1. Total Populations of the different continents") print("2. Percentage Change(%) for different countries") print("3. Exit Program") print(30 * '-') def calculate_continent_total_pop(): continent_pop = Counter() with open('a.txt') as f: # 跳过前两行表头,比for循环更简洁 next(f) next(f) for line in f: line = line.strip() if not line: continue splits = line.split(';') # 校验数据格式,避免索引越界 if len(splits) < 8: print(f"跳过格式错误的行: {line}") continue try: pop = int(splits[3].strip()) continent = splits[-1].strip() continent_pop[continent] += pop except ValueError: print(f"跳过数值错误的行: {line}") # 按人口从多到少排序,加千分位分隔符更易读 print("\n各大陆总人口统计:") for continent, total in continent_pop.most_common(): print(f"{continent}: {total:,}") def calculate_country_pop_change(): country_changes = {} with open('a.txt') as f: next(f) next(f) for line in f: line = line.strip() if not line: continue splits = line.split(';') if len(splits) < 8: print(f"跳过格式错误的行: {line}") continue try: change_rate = float(splits[6].strip()) country = splits[1].strip() country_changes[country] = change_rate except ValueError: print(f"跳过数值错误的行: {line}") # 按变化率从高到低排序 print("\n各国人口变化百分比:") for country, rate in sorted(country_changes.items(), key=lambda x: x[1], reverse=True): print(f"{country}: {rate}%") # 主循环逻辑 while True: show_main_menu() try: choice = int(input('请输入你的选择 [1-3]: ')) if choice == 1: calculate_continent_total_pop() elif choice == 2: calculate_country_pop_change() elif choice == 3: print("程序退出中...") break else: print("无效选项!请输入1-3之间的数字") except ValueError: print("输入无效!请输入整数")
这个修复版做了这些改进:
- 把菜单和功能拆成独立函数,代码更易维护
- 添加了退出选项,解决了无限循环问题
- 增加输入验证和数据格式校验,避免程序崩溃
- 优化了数字显示格式(千分位分隔符)
- 功能2改用普通字典,更贴合需求
内容的提问来源于stack exchange,提问作者sanjay mc'clough

