This commit is contained in:
2025-09-12 21:13:45 +08:00
parent 4052d53720
commit 14df704f6c
7 changed files with 20099 additions and 20061 deletions

File diff suppressed because it is too large Load Diff

View File

Before

Width:  |  Height:  |  Size: 178 KiB

After

Width:  |  Height:  |  Size: 178 KiB

View File

@@ -15,7 +15,7 @@ DATA_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'Data')
JSON_PATH = os.path.join(DATA_DIR, 'ClassCount.json')
# 工作表名称
SHEET_NAME = '招生'
SHEET_NAME = '班级' # 修正为正确的工作表名称
# 区域名称所在列
REGION_NAME_COLUMN = 'B'

View File

@@ -92,14 +92,19 @@ class YuCeUtil:
for area in enrollment_data_all:
if area.get('area_name') == self.area_name:
preschool_data = area.get('education_data', {}).get('preschool', {})
# 提取总入园人数和城乡分布
# 提取城乡分布数据并计算真实的total值
self.enrollment_data = {}
for year, data in preschool_data.items():
urban = data.get('urban', 0)
town = data.get('town', 0)
rural = data.get('rural', 0)
# 计算真实的total值而不是使用文件中可能错误的total
real_total = urban + town + rural
self.enrollment_data[year] = {
'total': data.get('total', 0),
'urban': data.get('urban', 0),
'town': data.get('town', 0),
'rural': data.get('rural', 0)
'total': real_total,
'urban': urban,
'town': town,
'rural': rural
}
area_found = True
break
@@ -117,6 +122,16 @@ class YuCeUtil:
for area in teacher_data_all:
if area.get('area_name') == self.area_name:
self.teacher_data = area.get('preschool_teachers', {})
# 处理2021-2023年staff数据为0的情况
for year in ['2021', '2022', '2023']:
if year in self.teacher_data:
# 使用前一年的数据进行估算
prev_year = str(int(year) - 1)
if prev_year in self.teacher_data:
self.teacher_data[year]['total_staff'] = self.teacher_data[prev_year].get('total_staff', 0)
self.teacher_data[year]['urban_staff'] = self.teacher_data[prev_year].get('urban_staff', 0)
self.teacher_data[year]['town_staff'] = self.teacher_data[prev_year].get('town_staff', 0)
self.teacher_data[year]['rural_staff'] = self.teacher_data[prev_year].get('rural_staff', 0)
area_found = True
break
@@ -133,7 +148,20 @@ class YuCeUtil:
area_found = False
for area in class_data_all:
if area.get('area_name') == self.area_name:
self.class_count_data = area.get('education_data', {}).get('preschool', {})
# 注意:这里数据结构可能与之前不同
if 'preschool_classes' in area:
self.class_count_data = area.get('preschool_classes', {})
else:
self.class_count_data = area.get('education_data', {}).get('preschool', {})
# 计算班级数的total值
for year, data in self.class_count_data.items():
if isinstance(data, dict) and 'urban' in data and 'town' in data and 'rural' in data:
# 计算真实的total值
urban = data.get('urban', 0)
town = data.get('town', 0)
rural = data.get('rural', 0)
data['total'] = urban + town + rural
area_found = True
break
@@ -167,6 +195,7 @@ class YuCeUtil:
three_years_later = str(int(year_str) + 3)
if three_years_later in self.enrollment_data:
# 使用计算出的真实total值
enrollment_count = self.enrollment_data.get(three_years_later, {}).get('total', 0)
if birth_count > 0 and enrollment_count > 0:
@@ -242,6 +271,7 @@ class YuCeUtil:
# 合并实际入园数据和预测入园数据
all_enrollment_data = {}
for year, data in self.enrollment_data.items():
# 使用计算出的真实total值
all_enrollment_data[year] = data.get('total', 0)
for year, count in self.forecast_results.items():
all_enrollment_data[str(year)] = count
@@ -279,7 +309,7 @@ class YuCeUtil:
else:
print(f" {current_year}年: 没有足够的有效历史数据计算在园人数")
# 计算基于5年平均的固定在园人数用于某些预测场景
# 计算基于5年入园数平均的固定在园人数(用于某些预测场景)
self.calculate_fixed_enrollment_in_school()
def calculate_fixed_enrollment_in_school(self):
@@ -352,6 +382,7 @@ class YuCeUtil:
# 计算历史城区招生比例
for year_str in sorted(self.enrollment_data.keys()):
# 使用计算出的真实total值
total_enrollment = self.enrollment_data.get(year_str, {}).get('total', 0)
urban_enrollment = self.enrollment_data.get(year_str, {}).get('urban', 0)
@@ -478,21 +509,23 @@ class YuCeUtil:
# 计算历史年份学位缺口
for year_str, class_data in self.class_count_data.items():
year = int(year_str)
if year_str in self.enrollment_data:
# 现有学位数=当年总班级数÷3×对应班额标准学前分3个年级
total_classes = class_data.get('total', 0)
enrollment_count = self.enrollment_data.get(year_str, {}).get('total', 0)
if total_classes > 0:
# 计算现有学位数
available_degrees = (total_classes / 3) * class_size_standard
# 计算缺口/富余(现有学位数-预测入园数)
gap = available_degrees - enrollment_count
self.degree_gap[year] = gap
if isinstance(class_data, dict): # 确保class_data是字典类型
year = int(year_str)
if year_str in self.enrollment_data:
# 现有学位数=当年总班级数÷3×对应班额标准学前分3个年级
total_classes = class_data.get('total', 0)
# 使用计算出的真实total值
enrollment_count = self.enrollment_data.get(year_str, {}).get('total', 0)
status = "富余" if gap >= 0 else "缺口"
print(f" {year}年班级数: {total_classes}, 入园人数: {enrollment_count}, 可用学位: {available_degrees:.0f}, {status}: {abs(gap):.0f}")
if total_classes > 0:
# 计算现有学位数
available_degrees = (total_classes / 3) * class_size_standard
# 计算缺口/富余(现有学位数-预测入园数)
gap = available_degrees - enrollment_count
self.degree_gap[year] = gap
status = "富余" if gap >= 0 else "缺口"
print(f" {year}年班级数: {total_classes}, 入园人数: {enrollment_count}, 可用学位: {available_degrees:.0f}, {status}: {abs(gap):.0f}")
# 预测未来年份学位缺口
for year in range(2025, 2030):
@@ -504,15 +537,20 @@ class YuCeUtil:
recent_years = [y for y in self.class_count_data.keys() if int(y) < year]
if recent_years:
latest_year = max(recent_years)
latest_classes = self.class_count_data.get(latest_year, {}).get('total', 0)
latest_enrollment = self.enrollment_data.get(latest_year, {}).get('total', 0)
if latest_enrollment > 0:
# 按比例增长
projected_classes = latest_classes * (enrollment_count / latest_enrollment)
latest_classes_data = self.class_count_data.get(latest_year, {})
# 确保latest_classes_data是字典类型
if isinstance(latest_classes_data, dict):
latest_classes = latest_classes_data.get('total', 0)
latest_enrollment = self.enrollment_data.get(latest_year, {}).get('total', 0)
if latest_enrollment > 0:
# 按比例增长
projected_classes = latest_classes * (enrollment_count / latest_enrollment)
else:
# 按标准班级数计算
projected_classes = enrollment_count / class_size_standard * 3 # 考虑3个年级
else:
# 按标准班级数计算
projected_classes = enrollment_count / class_size_standard * 3 # 考虑3个年级
projected_classes = 0
else:
# 按标准班级数计算
projected_classes = enrollment_count / class_size_standard * 3 # 考虑3个年级
@@ -653,6 +691,6 @@ if __name__ == "__main__":
print(f"\n正在预测{area}的学前教育数据...")
# 创建预测实例并运行预测
forecast = PreschoolEnrollmentForecast(data_directory, area)
forecast = YuCeUtil(data_directory, area)
forecast.run_forecast()