2021-10-24阳光分班之随机分班(后附源码)

本文介绍了一种模拟齐齐哈尔市28中阳光分班的随机算法,通过生成1200个学生姓名,利用Python编程实现按学号随机分配到22个班级,确保公平公正。过程包括读取姓名文件、构造学生信息、分班策略和结果保存。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

阳光分班之随机分班(后附源码)

思想:人选班

按学号开始选班

用初始可选择班级号(22)

学生学号随机选择22个班中的一个

装满一个班移除一个

然后循环直至列表为空

目的:

齐齐哈尔市28中目前是阳光分班,
# 即按照计算机程序设计的某种规则,随机分配1100个学生进入22个班级,避免了走后门进入某个老师的班级。
# 请自己生成1200个学生姓名或者下载百家姓姓名保存到文件中,然后读取文件姓名,自己设计算法实现学生分配,并把结果保存到文件中。

准备工作:

下载百家姓存文件 last_names1.txt ,last_names2.txt
百家姓


保存名字存文件 boy_name.txt , girl_name.txt
百家复姓


# 从文件读取内容用空格切割
# 按照空格分隔
# 高级写法(列表推导式)
# 颠覆我对语言结构的认知,python里面这个叫做列表推导式
def read_split(fileName, str):
    with open(fileName, 'r', encoding='utf-8') as f:
        for i in f:
            str.append([j for j in i.split(' ')])
    f.close()

# 总人数
count = 1200
# 学生信息列表
student_list = []
# 学号基数
id = 20190210000
import openpyxl
import random
import pandas as pd

随机生成取姓名匹配性别:

 # 百家姓单姓氏
    lastName1 = []
    read_split('resource/last_names1.txt', lastName1)
    # print('lastName1:')
    # print(lastName1[0])

    # 百家姓中双姓氏
    lastName2 = []
    read_split('resource/last_names2.txt', lastName2)
    # print("lastName2:")
    # print(lastName2[0])

    # 女孩名字
    girl_name = []
    read_split('resource/girl_name.txt', girl_name)
    # print("girl_name:")
    # print(girl_name[0])

    # 男孩名字
    boy_name = []
    read_split('resource/boy_name.txt', boy_name)
    # print('boy_name:')
    # print(boy_name[0])

    # 字辈
    zi = "应思士志永世其昌久远安定立正朝纲尚奉青田道义文光规矩方圆万代同邦"

    # 10%的机遇生成双数姓氏
    if random.choice(range(100)) > 10:
        lastName = random.choice(lastName1[0])
        # print(lastName)
    else:
        lastName = random.choice(lastName2[0])

    sex = random.choice(range(2))
    # 生成并一个名字 和 性别
    name_middle = ''

    if sex > 0:
        name = random.choice(girl_name[0])
        # print("女:")
        # print(name)
        if random.choice(range(2)) > 0:
            name_middle = random.choice(zi)  # 字辈
        new_name = str(lastName + name_middle + name)
        new_sex = '女'

    else:
        name = random.choice(boy_name[0])
        # print("男:")
        # print(name)
        if random.choice(range(2)) > 0:
            name_middle = random.choice(zi)
        new_name = str(lastName + name_middle + name)
        new_sex = '男'

随机生成学生成绩信息

 # 生成学号
    global id
    id += 1;

    # 随机生成年龄
    age = random.randint(16, 21)

    # 随机数学成绩
    math = random.randint(20, 150)

    # 随机语文成绩
    chinese = random.randint(70, 150)

    # 随机外语成绩
    foreign = random.randint(20, 150)

    # 随机化学成绩
    chemistry = random.randint(0, 100)

    # 随机物理成绩
    physics = random.randint(0, 110)

    # 随机生物成绩
    biologic = random.randint(30, 90)

    # 总分
    total_score = math + chinese + foreign + chinese + physics + biologic

加到列表中student_list

 	student_list.append([id, new_name, new_sex, age, math, chinese, foreign, chemistry, biologic, physics, total_score])
    # print(student_list)

构造1200学生信息

# 初始化
mun = 0
# 构造1200学生
while mun < count:
    random_student_info()
    mun += 1

创建excel头部

# 新建excel,改变sheet名字,并写入内容
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = '分班信息'
    ws.cell(row=1, column=1).value = "学号"
    ws.cell(row=1, column=2).value = "姓名"
    ws.cell(row=1, column=3).value = "性别"
    ws.cell(row=1, column=4).value = "年龄"
    ws.cell(row=1, column=5).value = "数学"
    ws.cell(row=1, column=6).value = "语文"
    ws.cell(row=1, column=7).value = "外语"
    ws.cell(row=1, column=8).value = "化学"
    ws.cell(row=1, column=9).value = "生物"
    ws.cell(row=1, column=10).value = "物理"
    ws.cell(row=1, column=11).value = "总分"
    ws.cell(row=1, column=12).value = "班级"
# 分班
# 思想:
#     人选班
#     按学号开始选班
#     用初始可选择班级号(22)
#     学生学号随机选择22个班中的一个
#     装满一个班移除一个
#     然后循环直至列表为空
# 1.按学号从前往后随机选班
    cd = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 标记数组
    c_id = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]  # 初始可选择班级号
    i, j = 2, 1     # 初始行列为 2,1
    for x in student_list:  # 学号为报名先后,遍历1200学生并选班
        j = 1   # 初始列为 1
        for y in x:
            ws.cell(row=i, column=j).value = y  # 学生信息写入excel
            j += 1  # 标记列
        q = random.choice(c_id)     # 随机选班
        ws.cell(row=i, column=j).value = q  # 写入班级号
        cd[q-1] += 1    # 标记出现次数
        if cd[q-1] == 50:  # 1100/22=50
            c_id.remove(q)      # 班级满了,移除,不在选择列表中
        i += 1  # 标记行
        if len(c_id) == 0:
            break   # 招满了,退出循环

保存

# 保存
    wb.save('./resource/notes.xlsx')
 # pandas.read_excel()的作用:将Excel文件读取到pandas DataFrame中
    stexcel = pd.read_excel('./resource/notes.xlsx',sheet_name='分班信息')
    # 表示pd按照A这个字段排序,inplace默认为False,如果该值为True,那么就会在当前的dataframe上操作。
    # ascending 默认等于True,按从小到大排列,改为False 按从大到小排。
    stexcel.sort_values(by='班级', inplace=True, ascending=True)

    print(stexcel)

结果1
结果2
结果3

调试记录:

1
2
3

4

反思:

我建议写一步,然后调试一步,写的时候很舒服,但调试起来好多小红点,脑壳昏!!!

注:txt文件最后不要有空格

注意列表的是不是嵌套一个列表

不同类型不能使用加号来进行拼接

总之,刚刚有好多bug没有及时记录,但还是解决了,建议下次先截个图,然后思考解决,防止下次忘记了

源码:

# -*- coding = utf-8 -*-
# @Time : 2021/10/24 9:43
# @Author : luxiaoguo
# @File : 阳光分班.py
# @Software : PyCharm

# @目的:1阳光分班程序:
# 齐齐哈尔市28中目前是阳光分班,
# 即按照计算机程序设计的某种规则,随机分配1100个学生进入22个班级,避免了走后门进入某个老师的班级。
# 请自己生成1200个学生姓名或者下载百家姓姓名保存到文件中,然后读取文件姓名,自己设计算法实现学生分配,并把结果保存到文件中。

# 总人数
count = 1200
# 学生信息列表
student_list = []
# 学号基数
id = 20190210000
import openpyxl
import random
import pandas as pd

# 操作创建插入保存excel表
def operation_excel():
    # fine_tune_no()
    # 新建excel,改变sheet名字,并写入内容
    wb = openpyxl.Workbook()
    ws = wb.active
    ws.title = '分班信息'
    ws.cell(row=1, column=1).value = "学号"
    ws.cell(row=1, column=2).value = "姓名"
    ws.cell(row=1, column=3).value = "性别"
    ws.cell(row=1, column=4).value = "年龄"
    ws.cell(row=1, column=5).value = "数学"
    ws.cell(row=1, column=6).value = "语文"
    ws.cell(row=1, column=7).value = "外语"
    ws.cell(row=1, column=8).value = "化学"
    ws.cell(row=1, column=9).value = "生物"
    ws.cell(row=1, column=10).value = "物理"
    ws.cell(row=1, column=11).value = "总分"
    ws.cell(row=1, column=12).value = "班级"

    # 初始化
    mun = 0
    # 构造1200学生
    while mun < count:
        random_student_info()
        mun += 1

    # 分班
    # 思想:
    #     人选班
    #     按学号开始选班
    #     用初始可选择班级号(22)
    #     学生学号随机选择22个班中的一个
    #     装满一个班移除一个
    #     然后循环直至列表为空

    # 1.按学号从前往后随机选班
    cd = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]  # 标记数组
    c_id = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22]  # 初始可选择班级号
    i, j = 2, 1     # 初始行列为 2,1
    for x in student_list:  # 学号为报名先后,遍历1200学生并选班
        j = 1   # 初始列为 1
        for y in x:
            ws.cell(row=i, column=j).value = y  # 学生信息写入excel
            j += 1  # 标记列
        q = random.choice(c_id)     # 随机选班
        ws.cell(row=i, column=j).value = q  # 写入班级号
        cd[q-1] += 1    # 标记出现次数
        if cd[q-1] == 50:  # 1100/22=50
            c_id.remove(q)      # 班级满了,移除,不在选择列表中
        i += 1  # 标记行
        if len(c_id) == 0:
            break   # 招满了,退出循环
    # print("c_id:")
    # print(c_id)
    # 保存
    wb.save('./resource/notes.xlsx')

    # pandas.read_excel()的作用:将Excel文件读取到pandas DataFrame中
    stexcel = pd.read_excel('./resource/notes.xlsx',sheet_name='分班信息')
    # 表示pd按照A这个字段排序,inplace默认为False,如果该值为True,那么就会在当前的dataframe上操作。
    # ascending 默认等于True,按从小到大排列,改为False 按从大到小排。
    stexcel.sort_values(by='班级', inplace=True, ascending=True)

    print(stexcel)




# 按照空格分隔
# 高级写法(列表推导式)
# 颠覆我对语言结构的认知,python里面这个叫做列表推导式
def read_split(fileName, str):
    with open(fileName, 'r', encoding='utf-8') as f:
        for i in f:
            str.append([j for j in i.split(' ')])
    f.close()


def random_student_info():
    # 百家姓单姓氏
    lastName1 = []
    read_split('resource/last_names1.txt', lastName1)
    # print('lastName1:')
    # print(lastName1[0])

    # 百家姓中双姓氏
    lastName2 = []
    read_split('resource/last_names2.txt', lastName2)
    # print("lastName2:")
    # print(lastName2[0])

    # 女孩名字
    girl_name = []
    read_split('resource/girl_name.txt', girl_name)
    # print("girl_name:")
    # print(girl_name[0])

    # 男孩名字
    boy_name = []
    read_split('resource/boy_name.txt', boy_name)
    # print('boy_name:')
    # print(boy_name[0])

    # 字辈
    zi = "应思士志永世其昌久远安定立正朝纲尚奉青田道义文光规矩方圆万代同邦"

    # 10%的机遇生成双数姓氏
    if random.choice(range(100)) > 10:
        lastName = random.choice(lastName1[0])
        # print(lastName)
    else:
        lastName = random.choice(lastName2[0])

    sex = random.choice(range(2))
    # 生成并一个名字 和 性别
    name_middle = ''

    if sex > 0:
        name = random.choice(girl_name[0])
        # print("女:")
        # print(name)
        if random.choice(range(2)) > 0:
            name_middle = random.choice(zi)  # 字辈
        new_name = str(lastName + name_middle + name)
        new_sex = '女'

    else:
        name = random.choice(boy_name[0])
        # print("男:")
        # print(name)
        if random.choice(range(2)) > 0:
            name_middle = random.choice(zi)
        new_name = str(lastName + name_middle + name)
        new_sex = '男'

    # 生成学号
    global id
    id += 1;

    # 随机生成年龄
    age = random.randint(16, 21)

    # 随机数学成绩
    math = random.randint(20, 150)

    # 随机语文成绩
    chinese = random.randint(70, 150)

    # 随机外语成绩
    foreign = random.randint(20, 150)

    # 随机化学成绩
    chemistry = random.randint(0, 100)

    # 随机物理成绩
    physics = random.randint(0, 110)

    # 随机生物成绩
    biologic = random.randint(30, 90)

    # 总分
    total_score = math + chinese + foreign + chinese + physics + biologic

    student_list.append([id, new_name, new_sex, age, math, chinese, foreign, chemistry, biologic, physics, total_score])
    # print(student_list)


if __name__ == '__main__':
    operation_excel()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值