From ec35818b133be8d435e37af33acc5cdec6bc25c0 Mon Sep 17 00:00:00 2001 From: HuangHai <10402852@qq.com> Date: Thu, 11 Sep 2025 21:34:02 +0800 Subject: [PATCH] 'commit' --- Controller/EducationDataController.py | 33 +++++ .../EducationDataController.cpython-310.pyc | Bin 892 -> 1361 bytes Model/EducationDataModel.py | 67 +++++++++- .../EducationDataModel.cpython-310.pyc | Bin 7404 -> 9144 bytes Test/read_population_data.py | 52 ++++++++ Test/test_population_data_interface.py | 124 ++++++++++++++++++ 6 files changed, 271 insertions(+), 5 deletions(-) create mode 100644 Test/read_population_data.py create mode 100644 Test/test_population_data_interface.py diff --git a/Controller/EducationDataController.py b/Controller/EducationDataController.py index d609fe8..1a132a4 100644 --- a/Controller/EducationDataController.py +++ b/Controller/EducationDataController.py @@ -31,4 +31,37 @@ async def get_education_data_by_year( } +@router.get("/populationByYear") +async def get_population_data_by_year( + year: int = Query(default=2023, ge=2015, le=2028, + description="年份: 2015-2028范围内的年份") +): + """获取指定年份的云南省人口数据""" + try: + # 调用EducationDataModel的方法获取人口数据 + data = EducationDataModel.get_population_data_by_year(year) + + if data: + # 返回包含状态和数据的响应 + return { + "code": 200, + "message": "success", + "data": data + } + else: + # 未找到数据的情况 + return { + "code": 404, + "message": f"未找到{year}年的云南省人口数据", + "data": None + } + except Exception as e: + # 异常处理 + return { + "code": 500, + "message": f"获取数据失败: {str(e)}", + "data": None + } + + diff --git a/Controller/__pycache__/EducationDataController.cpython-310.pyc b/Controller/__pycache__/EducationDataController.cpython-310.pyc index 8fdf69f3c1ba4d3651189c01db88cc3430ca84c8..60b2777939025159a936541d6db1328e20d596e7 100644 GIT binary patch delta 626 zcmZ`$O=uHQ5Pmbe+1;#3nm>PH^&(h^9=xds@t{|!U=gVY!i<^N^ z^6~a(y_q-y^Uaf2H9NAQ@sZ|@+(?qA8j&Tq9_8r?me0JpTY<4acl~0~cHNE=s6~g{ zfj&c#HDw1Xw><0n4`A$P>o{J@bQH0V=tYVk0K3CPuGPSckZpa!d^St3bE#8hr|eH# zUdg$0p)%RJ3`gr_N-V-$&SM);WzV4oRS-!I9IL>UwsMV4Fs|}Qm8~(Ztt(vLeN~x< zl{3I<2t>^d9`%$eF2NdG$K5K8O){?6a2|y3KI;*>-!e*X@QYFZxfm`pcUlM)e{tAwf`jOk?{|^7`$U{Rbby`&<4f zMMUyHhH;UW-5G+sDpWGT=#=f%3wtXm$c+|mRtgo{5@NqBKOo_tgxp^^EIp}qjIKLI zfD5RZs3Ix|2*wT?=Flc0sKm%i?-&dCd)PCcHv|2a<$6}RB#^OIL^*p!e$FuakIGO_ nN(IKb8HfAR_Ia9_xl%OAVvtY`#XtmgpbijX1LM$MlpOp4w3@OQ delta 170 zcmcb}^@oiwpO=@50SFGCK9sSKc_N<-W7tIPP_`8QU 0.01: + print("\n注意:总人口与城镇人口+乡村人口存在差异") + print(f"差异值: {abs(total - urban_rural_sum):.2f} 万人") + @staticmethod def print_education_data(data, year): """打印教育数据""" @@ -268,20 +321,24 @@ class EducationDataModel: for file_path in [EducationDataModel.SCHOOL_COUNT_FILE, EducationDataModel.TEACHER_COUNT_FILE, EducationDataModel.ENROLLMENT_COUNT_FILE, - EducationDataModel.ADMISSION_COUNT_FILE]: + EducationDataModel.ADMISSION_COUNT_FILE, + EducationDataModel.POPULATION_FILE]: # 新增:检查人口数据文件 if os.path.exists(file_path): print(f"找到数据文件: {file_path}") else: print(f"警告:数据文件不存在: {file_path}") - # 获取数据 + # 获取并打印教育数据 education_data = EducationDataModel.get_education_data_by_year(year) - - # 打印数据 if education_data: EducationDataModel.print_education_data(education_data, year) else: - print("未获取到任何数据") + print("未获取到任何教育数据") + + # 新增:获取并打印人口数据 + print("\n" + "=" * 50) + population_data = EducationDataModel.get_population_data_by_year(year) + EducationDataModel.print_population_data(population_data) except Exception as e: print(f"获取数据时发生错误: {e}") diff --git a/Model/__pycache__/EducationDataModel.cpython-310.pyc b/Model/__pycache__/EducationDataModel.cpython-310.pyc index 2ccbacf1470fb3d458d2b023858d634e94901a61..7447f89d29fcf69dd59596d989f194236a152505 100644 GIT binary patch delta 2448 zcmZuyZERCj7{2G;+pfLsx~^N-uH8ljCRAj6MIwqI@;MlTI1pXHrrRm3V|3&8-msNB zirbO_k5?G=Q`gX?EnM(Py@&i{N!VVF#P)QnnXP;;A=Q~Fp^10=bYm={&=eo0;ET7YKQfIbCTcWRpJNUT@nB`<7os*rI>qUPpe^|8mPo z0*1oR1jGt$E427m01B5P3fIY}Nk2SOf<}Px8Xxy4A|)Dkm81NGFh~eTg%(aRX>ex! zg2ril%1p&5mxiY%P*WPlfW^GPQqs1-WLaRb7F(z^ZtfSA5>2G$YEH2X^78A7)#y>1 zpQH9c9(x-(O@#9+RiDzol-$XgD?`)w#&Q?mnHhg$`rf_V===FgxAGTnsBYM1e*EM6 zBe!#-mviTC%|)p$@Z|1(#zxK$XwEv7ZYA6m>gn!LyTVGeJ0{~9W}R(OS?MS;XPv6t z7LGAX(umADWmW#q*lalqiY8d5kQ`PbL9@IJ63V*}8WDCQ>_KQkcpl&Z&KZRW16rlnY(>zu! zHE9Iu)NIr#^h+=fo)#8orBa%wwyPqwPYB6bS1EHj&;>)mF>5blc4zUBSx-6hxc;`f-!5-pe&7t>lYNzjV5?ORn&7_l!sx}-q{JOi+q@Nc9FP$ zY(XEZ-~4$!cM)oOzJAp@IJ*2~IzN6sH+s|X&y{%65JfYq3Kb6-q%m{t0~J4-bIJ&) zSXCg6*}NYP-2doYqGIL39~+lH`?(PqFiINV;s=IOiX{KQznjOr+g&b@hgW@I?P^pX%7)*empf%;>oD{t)l zIWe?ZMFmOu%=P@x=xSU@~>kdTG= zh!-0E?Shw}rH+VyCzfxgYCHRmYy%DN?WU2g2F$u3X{MvmyvhNVr55476xsVNwdp>T>p*G*hZP&Eb&OU{Jq!M#P~8J4H@$L7V7{97K`O<>_AusGo3Y7r#x>y7@P`5=S`YxQ1#z3nATd_ lldzj8YYByLxuFo;ENnVECS{k@5oCw;$(mOE7UZ`_J#c^M7w&W?uDuYxj(~ z-A*Fcu8;3V-nJ}wCg~bkm>ZwgxXRtLWCku&4r$!OD=hX()_A4GKFMD0v)C`$&jS_* zBnNrO;-KU(k60X%T*a#`4oj}*QC>R>@(&SSH$alHlJ^iFA50sWvC&@f7(SS{Xci!B zepikI#LW)dHU=p(?U+$u&|FvFC~(_+qD@iPvYcPvFD2I|nj;~z*Ovjvn9F`UK&N;S z*yrlP!~v9p;zytrK8wbnZa%Ad577?%+KGapoV}yDWp~T)R(QU)oBkx?Q|(EgO>W~+ z^~g8-1+)F4xh^$5%zDYCPyvjx%jHE!9+p6FG6-jRct9S}831ylT6)`m9*WL9S%L!1 zQ@zK4qAO3Or$EjT?ie64Z^z0_$B3ccyaJ@40LcaAURhq*>dlko+;P=iV0l*bEDQNvIHw zv7M0;9m|&3^|UckvJXvWvPM=vEDQBMk&D%xwdp(1XeezcUX&9kzJKDERASfCnNbGv zz#65ciUt}mg#kY0zf~qZbt+8pf`^J 0.01: + print("\n注意:总人口与城镇人口+乡村人口存在差异") + print(f"差异值: {abs(total_population - (urban_population + rural_population)):.2f} 万人") \ No newline at end of file diff --git a/Test/test_population_data_interface.py b/Test/test_population_data_interface.py new file mode 100644 index 0000000..74879ad --- /dev/null +++ b/Test/test_population_data_interface.py @@ -0,0 +1,124 @@ +import requests +import json +import time + +# API基础URL +EDUCATION_DATA_BASE_URL = "http://localhost:8100/EducationData" + +# 测试年份 +test_years = [2023, 2022, 2024] + + +def test_population_data_by_year(): + """测试获取指定年份人口数据接口""" + print("\n===== 测试 /EducationData/populationByYear 接口 =====") + + # 测试不同年份的数据 + for year in test_years: + url = f"{EDUCATION_DATA_BASE_URL}/populationByYear?year={year}" + print(f"\n测试 {year} 年人口数据:") + + try: + response = requests.get(url) + response.raise_for_status() # 如果状态码不是200,抛出异常 + + data = response.json() + print(f"响应状态码: {response.status_code}") + print(f"响应数据: {json.dumps(data, ensure_ascii=False, indent=2)}") + + # 验证返回数据的基本结构 + assert "code" in data, "返回数据缺少code字段" + assert "message" in data, "返回数据缺少message字段" + assert "data" in data, "返回数据缺少data字段" + assert data["code"] == 200, f"状态码不匹配,期望: 200,实际: {data['code']}" + + # 验证数据内容 + if data["data"]: + # 检查数据项的结构 + population_data = data["data"] + assert "year" in population_data, "数据缺少year字段" + assert "total_population" in population_data, "数据缺少total_population字段" + assert "birth_population" in population_data, "数据缺少birth_population字段" + assert "urban_population" in population_data, "数据缺少urban_population字段" + assert "rural_population" in population_data, "数据缺少rural_population字段" + assert "urbanization_rate" in population_data, "数据缺少urbanization_rate字段" + + # 检查数值类型 + assert isinstance(population_data["year"], int), "year应为整数类型" + assert isinstance(population_data["total_population"], (int, float)), "total_population应为数值类型" + assert isinstance(population_data["birth_population"], (int, float)), "birth_population应为数值类型" + assert isinstance(population_data["urban_population"], (int, float)), "urban_population应为数值类型" + assert isinstance(population_data["rural_population"], (int, float)), "rural_population应为数值类型" + assert isinstance(population_data["urbanization_rate"], (int, float)), "urbanization_rate应为数值类型" + + # 检查年份是否匹配 + assert population_data["year"] == year, f"年份不匹配,期望: {year},实际: {population_data['year']}" + + print(f"✅ {year} 年人口数据验证通过") + else: + print(f"⚠️ {year} 年未返回人口数据") + + except requests.exceptions.RequestException as e: + print(f"❌ 请求失败: {e}") + except AssertionError as e: + print(f"❌ 数据验证失败: {e}") + + # 添加短暂延迟,避免请求过于频繁 + time.sleep(0.5) + + # 测试边界值 + print("\n===== 测试边界值 =====") + + # 测试最小值年份 + min_year = 2015 + url = f"{EDUCATION_DATA_BASE_URL}/populationByYear?year={min_year}" + print(f"\n测试最小值年份 {min_year}:") + try: + response = requests.get(url) + response.raise_for_status() + data = response.json() + print(f"响应状态码: {response.status_code}") + if data["code"] == 200 or data["code"] == 404: + print(f"✅ 最小值年份测试通过") + else: + print(f"❌ 状态码异常: {data['code']}") + except requests.exceptions.RequestException as e: + print(f"❌ 请求失败: {e}") + + # 测试最大值年份 + max_year = 2028 + url = f"{EDUCATION_DATA_BASE_URL}/populationByYear?year={max_year}" + print(f"\n测试最大值年份 {max_year}:") + try: + response = requests.get(url) + response.raise_for_status() + data = response.json() + print(f"响应状态码: {response.status_code}") + if data["code"] == 200 or data["code"] == 404: + print(f"✅ 最大值年份测试通过") + else: + print(f"❌ 状态码异常: {data['code']}") + except requests.exceptions.RequestException as e: + print(f"❌ 请求失败: {e}") + + # 测试超出范围的年份 + invalid_year = 2030 + url = f"{EDUCATION_DATA_BASE_URL}/populationByYear?year={invalid_year}" + print(f"\n测试超出范围的年份 {invalid_year}:") + try: + response = requests.get(url) + if response.status_code == 422: # FastAPI的验证错误状态码 + print(f"响应状态码: {response.status_code}") + print(f"✅ 超出范围年份正确返回验证错误") + else: + data = response.json() + print(f"响应状态码: {response.status_code}") + print(f"响应数据: {json.dumps(data, ensure_ascii=False, indent=2)}") + print(f"❌ 期望状态码422,实际: {response.status_code}") + except requests.exceptions.RequestException as e: + print(f"❌ 请求失败: {e}") + + +if __name__ == "__main__": + # 测试新添加的人口数据接口 + test_population_data_by_year() \ No newline at end of file