'commit'
This commit is contained in:
252
Test/get_education_data_by_year.py
Normal file
252
Test/get_education_data_by_year.py
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
import json
|
||||||
|
import os
|
||||||
|
|
||||||
|
# 定义学段映射关系
|
||||||
|
EDUCATION_STAGES = {
|
||||||
|
'preschool': '学前',
|
||||||
|
'primary': '小学',
|
||||||
|
'junior': '初中',
|
||||||
|
'senior': '高中',
|
||||||
|
'vocational': '中职'
|
||||||
|
}
|
||||||
|
|
||||||
|
# 数据文件路径
|
||||||
|
DATA_DIR = os.path.abspath(os.path.join(os.path.dirname(__file__), "../Data"))
|
||||||
|
SCHOOL_COUNT_FILE = os.path.join(DATA_DIR, "SchoolCount.json")
|
||||||
|
TEACHER_COUNT_FILE = os.path.join(DATA_DIR, "TeacherCount.json")
|
||||||
|
ENROLLMENT_COUNT_FILE = os.path.join(DATA_DIR, "ZaiXiaoShengCount.json")
|
||||||
|
ADMISSION_COUNT_FILE = os.path.join(DATA_DIR, "ZhaoShengCount.json")
|
||||||
|
|
||||||
|
|
||||||
|
def load_json_file(file_path):
|
||||||
|
"""加载JSON文件数据"""
|
||||||
|
try:
|
||||||
|
with open(file_path, "r", encoding="utf-8") as f:
|
||||||
|
return json.load(f)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"加载文件 {file_path} 失败: {e}")
|
||||||
|
return []
|
||||||
|
|
||||||
|
|
||||||
|
def get_province_data(data_list):
|
||||||
|
"""从数据列表中获取云南省的数据"""
|
||||||
|
if not isinstance(data_list, list):
|
||||||
|
print(f"数据列表不是预期的列表类型: {type(data_list)}")
|
||||||
|
return None
|
||||||
|
|
||||||
|
for item in data_list:
|
||||||
|
if isinstance(item, dict) and item.get("area_name") == "云南省":
|
||||||
|
return item
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def get_school_count_by_year_and_stage(year, stage):
|
||||||
|
"""获取指定年份和学段的学校总数"""
|
||||||
|
school_data = load_json_file(SCHOOL_COUNT_FILE)
|
||||||
|
province_data = get_province_data(school_data)
|
||||||
|
|
||||||
|
if not province_data:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 根据学段获取对应的学校数据字段名
|
||||||
|
stage_field_mapping = {
|
||||||
|
'preschool': 'preschool_schools',
|
||||||
|
'primary': 'primary_schools',
|
||||||
|
'junior': 'junior_schools',
|
||||||
|
'senior': 'senior_schools',
|
||||||
|
'vocational': 'vocational_schools'
|
||||||
|
}
|
||||||
|
|
||||||
|
field_name = stage_field_mapping.get(stage)
|
||||||
|
if not field_name or field_name not in province_data:
|
||||||
|
print(f"学段 {stage} 对应的学校数据字段不存在")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
year_data = province_data[field_name].get(str(year))
|
||||||
|
if not year_data or not isinstance(year_data, dict):
|
||||||
|
print(f"年份 {year} 的学校数据不存在或格式不正确")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 计算城区、镇区、乡村的学校总数
|
||||||
|
try:
|
||||||
|
total_schools = year_data.get('urban', 0) + year_data.get('town', 0) + year_data.get('rural', 0)
|
||||||
|
return total_schools
|
||||||
|
except Exception as e:
|
||||||
|
print(f"计算学校总数时出错: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_teacher_count_by_year_and_stage(year, stage):
|
||||||
|
"""获取指定年份和学段的教职工总数"""
|
||||||
|
teacher_data = load_json_file(TEACHER_COUNT_FILE)
|
||||||
|
province_data = get_province_data(teacher_data)
|
||||||
|
|
||||||
|
if not province_data:
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 根据学段获取对应的教职工数据字段名
|
||||||
|
stage_field_mapping = {
|
||||||
|
'preschool': 'preschool_teachers',
|
||||||
|
'primary': 'primary_teachers',
|
||||||
|
'junior': 'junior_teachers',
|
||||||
|
'senior': 'senior_teachers',
|
||||||
|
'vocational': 'vocational_teachers'
|
||||||
|
}
|
||||||
|
|
||||||
|
field_name = stage_field_mapping.get(stage)
|
||||||
|
if not field_name or field_name not in province_data:
|
||||||
|
print(f"学段 {stage} 对应的教职工数据字段不存在")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
year_data = province_data[field_name].get(str(year))
|
||||||
|
if not year_data or not isinstance(year_data, dict):
|
||||||
|
print(f"年份 {year} 的教职工数据不存在或格式不正确")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 优先使用total_staff,如果为0或不存在,则返回教师总数
|
||||||
|
try:
|
||||||
|
total_staff = year_data.get('total_staff', 0)
|
||||||
|
if total_staff == 0:
|
||||||
|
total_staff = year_data.get('total_teacher', 0)
|
||||||
|
return total_staff
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取教职工总数时出错: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_enrollment_count_by_year_and_stage(year, stage):
|
||||||
|
"""获取指定年份和学段的在校生总数"""
|
||||||
|
enrollment_data = load_json_file(ENROLLMENT_COUNT_FILE)
|
||||||
|
province_data = get_province_data(enrollment_data)
|
||||||
|
|
||||||
|
if not province_data or 'student_data' not in province_data:
|
||||||
|
print("未找到学生数据")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
stage_data = province_data['student_data'].get(stage)
|
||||||
|
if not stage_data:
|
||||||
|
print(f"学段 {stage} 的学生数据不存在")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
year_data = stage_data.get(str(year))
|
||||||
|
if not year_data or not isinstance(year_data, dict):
|
||||||
|
print(f"年份 {year} 的学生数据不存在或格式不正确")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 返回在校生总数
|
||||||
|
try:
|
||||||
|
return year_data.get('total', 0)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取在校生总数时出错: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_admission_count_by_year_and_stage(year, stage):
|
||||||
|
"""获取指定年份和学段的招生总数"""
|
||||||
|
admission_data = load_json_file(ADMISSION_COUNT_FILE)
|
||||||
|
province_data = get_province_data(admission_data)
|
||||||
|
|
||||||
|
if not province_data or 'education_data' not in province_data:
|
||||||
|
print("未找到教育数据")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
stage_data = province_data['education_data'].get(stage)
|
||||||
|
if not stage_data:
|
||||||
|
print(f"学段 {stage} 的教育数据不存在")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
year_data = stage_data.get(str(year))
|
||||||
|
if not year_data or not isinstance(year_data, dict):
|
||||||
|
print(f"年份 {year} 的教育数据不存在或格式不正确")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
# 返回招生总数
|
||||||
|
try:
|
||||||
|
return year_data.get('total', 0)
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取招生总数时出错: {e}")
|
||||||
|
return 0
|
||||||
|
|
||||||
|
|
||||||
|
def get_education_data_by_year(year):
|
||||||
|
"""获取指定年份所有学段的教育数据"""
|
||||||
|
result = []
|
||||||
|
|
||||||
|
for stage_code, stage_name in EDUCATION_STAGES.items():
|
||||||
|
# 获取各类数据(增加异常处理)
|
||||||
|
try:
|
||||||
|
school_count = get_school_count_by_year_and_stage(year, stage_code)
|
||||||
|
teacher_count = get_teacher_count_by_year_and_stage(year, stage_code)
|
||||||
|
enrollment_count = get_enrollment_count_by_year_and_stage(year, stage_code)
|
||||||
|
admission_count = get_admission_count_by_year_and_stage(year, stage_code)
|
||||||
|
|
||||||
|
# 转换为万人单位
|
||||||
|
teacher_count_10k = round(teacher_count / 10000, 2) if teacher_count else 0
|
||||||
|
enrollment_count_10k = round(enrollment_count / 10000, 2) if enrollment_count else 0
|
||||||
|
admission_count_10k = round(admission_count / 10000, 2) if admission_count else 0
|
||||||
|
|
||||||
|
# 添加到结果列表
|
||||||
|
result.append({
|
||||||
|
'education_stage': stage_name,
|
||||||
|
'school_count': school_count,
|
||||||
|
'teacher_count_10k': teacher_count_10k,
|
||||||
|
'enrollment_count_10k': enrollment_count_10k,
|
||||||
|
'admission_count_10k': admission_count_10k
|
||||||
|
})
|
||||||
|
except Exception as e:
|
||||||
|
print(f"处理学段 {stage_name} 时出错: {e}")
|
||||||
|
# 出错时添加一个默认的空数据条目
|
||||||
|
result.append({
|
||||||
|
'education_stage': stage_name,
|
||||||
|
'school_count': 0,
|
||||||
|
'teacher_count_10k': 0,
|
||||||
|
'enrollment_count_10k': 0,
|
||||||
|
'admission_count_10k': 0
|
||||||
|
})
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
|
||||||
|
def print_education_data(data, year):
|
||||||
|
"""打印教育数据"""
|
||||||
|
print(f"\n===== {year}年云南省各学段教育数据统计(单位:学校总数-个,其余-万人)=====")
|
||||||
|
print(f"{'学段':<8}{'学校总数':<10}{'教职工总数':<12}{'在校生总数':<12}{'招生总数':<12}")
|
||||||
|
print("=" * 60)
|
||||||
|
|
||||||
|
for item in data:
|
||||||
|
print(f"{item['education_stage']:<8}{item['school_count']:<10}{item['teacher_count_10k']:<12.2f}{item['enrollment_count_10k']:<12.2f}{item['admission_count_10k']:<12.2f}")
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""主函数"""
|
||||||
|
# 默认查询2023年数据
|
||||||
|
year = 2023
|
||||||
|
|
||||||
|
try:
|
||||||
|
print(f"正在获取 {year} 年数据...")
|
||||||
|
print(f"数据目录: {DATA_DIR}")
|
||||||
|
|
||||||
|
# 检查数据文件是否存在
|
||||||
|
for file_path in [SCHOOL_COUNT_FILE, TEACHER_COUNT_FILE, ENROLLMENT_COUNT_FILE, ADMISSION_COUNT_FILE]:
|
||||||
|
if os.path.exists(file_path):
|
||||||
|
print(f"找到数据文件: {file_path}")
|
||||||
|
else:
|
||||||
|
print(f"警告:数据文件不存在: {file_path}")
|
||||||
|
|
||||||
|
# 获取数据
|
||||||
|
education_data = get_education_data_by_year(year)
|
||||||
|
|
||||||
|
# 打印数据
|
||||||
|
if education_data:
|
||||||
|
print_education_data(education_data, year)
|
||||||
|
else:
|
||||||
|
print("未获取到任何数据")
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"获取数据时发生错误: {e}")
|
||||||
|
import traceback
|
||||||
|
traceback.print_exc()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@@ -1,135 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="zh-CN">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8">
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
||||||
<title>云南省学前教育数据</title>
|
|
||||||
<link rel="stylesheet" href="css/style.css">
|
|
||||||
<script src="js/echarts.min.js"></script>
|
|
||||||
<script src="js/jquery-3.7.1.min.js"></script>
|
|
||||||
<style>
|
|
||||||
.chart-controls {
|
|
||||||
margin: 20px 0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
.btn-group {
|
|
||||||
display: inline-flex;
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
||||||
}
|
|
||||||
.btn {
|
|
||||||
padding: 10px 20px;
|
|
||||||
border: none;
|
|
||||||
background: #f0f0f0;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: all 0.3s;
|
|
||||||
}
|
|
||||||
.btn.active {
|
|
||||||
background: #409eff;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
.btn:hover:not(.active) {
|
|
||||||
background: #e0e0e0;
|
|
||||||
}
|
|
||||||
.container {
|
|
||||||
max-width: 1200px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
text-align: center;
|
|
||||||
color: #333;
|
|
||||||
margin-bottom: 30px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<div class="container">
|
|
||||||
<h1>学前教育发展规模预测</h1>
|
|
||||||
|
|
||||||
<div class="chart-controls">
|
|
||||||
<div class="btn-group">
|
|
||||||
<button class="btn active" data-type="enroll">入园数总量</button>
|
|
||||||
<button class="btn" data-type="inschool">在园数总量</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div id="preschoolChart" style="width: 100%; height: 500px;"></div>
|
|
||||||
<div id="message" class="message"></div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
// 初始化图表
|
|
||||||
var preschoolChart = echarts.init(document.getElementById('preschoolChart'));
|
|
||||||
var chartData = null;
|
|
||||||
var currentType = 'enroll';
|
|
||||||
|
|
||||||
// 显示加载状态
|
|
||||||
function showLoading() {
|
|
||||||
preschoolChart.showLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 隐藏加载状态
|
|
||||||
function hideLoading() {
|
|
||||||
preschoolChart.hideLoading();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 显示错误信息
|
|
||||||
function showError(message) {
|
|
||||||
$('#message').text('错误: ' + message);
|
|
||||||
console.error(message);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 渲染图表
|
|
||||||
function renderChart() {
|
|
||||||
if (!chartData) return;
|
|
||||||
|
|
||||||
var option = JSON.parse(JSON.stringify(chartData));
|
|
||||||
|
|
||||||
// 根据用户要求,现在显示所有系列数据,不需要过滤
|
|
||||||
preschoolChart.setOption(option);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 加载学前教育数据
|
|
||||||
function loadPreschoolData() {
|
|
||||||
showLoading();
|
|
||||||
|
|
||||||
// 根据当前类型加载不同数据
|
|
||||||
var url = currentType === 'enroll' ?
|
|
||||||
'/RuYuanZaiYuan/school/preschool/chart' :
|
|
||||||
'/RuYuanZaiYuan/school/preschool/inschool/chart';
|
|
||||||
|
|
||||||
$.getJSON(url)
|
|
||||||
.done(function(data) {
|
|
||||||
chartData = data;
|
|
||||||
renderChart();
|
|
||||||
})
|
|
||||||
.fail(function(jqXHR, textStatus, errorThrown) {
|
|
||||||
showError(errorThrown || '获取数据失败,请检查接口是否正常');
|
|
||||||
})
|
|
||||||
.always(function() {
|
|
||||||
hideLoading();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// 按钮点击事件
|
|
||||||
$(document).ready(function() {
|
|
||||||
loadPreschoolData();
|
|
||||||
|
|
||||||
$('.btn').click(function() {
|
|
||||||
$('.btn').removeClass('active');
|
|
||||||
$(this).addClass('active');
|
|
||||||
currentType = $(this).data('type');
|
|
||||||
loadPreschoolData(); // 点击按钮后重新加载数据,而不是只渲染
|
|
||||||
});
|
|
||||||
|
|
||||||
// 窗口大小变化时调整图表
|
|
||||||
$(window).resize(function() {
|
|
||||||
preschoolChart.resize();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
Reference in New Issue
Block a user