From 963a28fd4602c82d4e75d42f3b41165a82fe1c49 Mon Sep 17 00:00:00 2001 From: HCha Date: Mon, 7 Nov 2022 17:19:16 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BA=A4a1878=E7=89=88=E6=9C=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- config.data | 8 +++ names.xls | Bin 0 -> 38912 bytes 点名器.pyw | 189 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 config.data create mode 100644 names.xls create mode 100644 点名器.pyw diff --git a/config.data b/config.data new file mode 100644 index 0000000..24b934b --- /dev/null +++ b/config.data @@ -0,0 +1,8 @@ +8,+ +9,+ +10,+ +11,- +12,- +13,- +14,0 +15,0 \ No newline at end of file diff --git a/names.xls b/names.xls new file mode 100644 index 0000000000000000000000000000000000000000..f010e16e5ecbed2a20e4101f6d556828559a5220 GIT binary patch literal 38912 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 XSsPMV1d7%k`sIis_rC!QOZNW@mjk0e literal 0 HcmV?d00001 diff --git a/点名器.pyw b/点名器.pyw new file mode 100644 index 0000000..b4dd851 --- /dev/null +++ b/点名器.pyw @@ -0,0 +1,189 @@ +import xlrd as excel +from tkinter import * +import tkinter.messagebox as msgbox +import random +import sys +import win32con, win32api + +gui = Tk() + +class Student(object): + name = "" + subject = "" + id = "" + class_name = "" + + def __init__(self,id,class_name,subject,name): + self.id = id + self.class_name = class_name + self.subject = subject + self.name = name + +protection_override = False +up_percent = 30 +down_persent = 40 +filename = "names.xls" +configname = "config.data" +elim_rows = 1 +gui_size = "620x200" +percent_override = True + +try: + excel_data = excel.open_workbook(filename) + table = excel_data.sheets()[0] + win32api.SetFileAttributes(filename,win32con.FILE_ATTRIBUTE_HIDDEN) +except FileNotFoundError: + msgbox.showerror('找不到数据库文件', '在相同目录下未能找到 names.xls 文件,请确认您的文件存在', parent=gui) + sys.exit() + +try: + cols = table.ncols + rows = table.nrows + assert cols == 4 + assert rows > 1 +except AssertionError: + msgbox.showerror('数据库文件格式不正确', '数据库文件内行/列数不合法,请确认数据库文件拥有超过1的行数和等于4的列数,当前行数:' + str(rows) + ' 当前列数:' + str(cols), parent=gui) + sys.exit() + +elim_id = [] +up_id = [] +down_id = [] + +try: + with open(configname,'r') as file: + win32api.SetFileAttributes(configname,win32con.FILE_ATTRIBUTE_HIDDEN) + config = file.read().splitlines() + for unit in config: + temp = unit.split(",") + if temp[1] == '0': + elim_id.append(int(temp[0])) + elif temp[1] == '+': + up_id.append(int(temp[0])) + elif temp[1] == "-": + down_id.append(int(temp[0])) + else: + pass +except: + percent_override = False + +up_percent = len(up_id) * 5 if len(up_id) <= 6 else 30 +down_percent = len(down_id) * 8 if len(down_id) <= 5 else 40 + +students = [] +classes = [] +subjects = [] +filter = [] + +last_choice = "" + +# print("读取数据库成功:" + str(cols) + "列 " + str(rows) + "行") + +for i in range(elim_rows,rows): + tmp_list = [str(table.cell_value(i,j)) for j in range(0,cols)] + if (int(float(tmp_list[0])) not in elim_id): + student = Student(tmp_list[0],tmp_list[1],tmp_list[2],tmp_list[3]) + students.append(student) + +cur_stu = [] + +cur_stu = students[:] + +for student in students: + if student.class_name not in classes: + classes.append(student.class_name) + if student.subject not in subjects: + subjects.append(student.subject) + +gui.title("点名器") +gui.geometry(gui_size) +gui.resizable(0,0) +gui.configure(bg = "white") + +cur_name = StringVar() + +def upd_name(name): + cur_name.set(name) + +upd_name("") + +listbox = Listbox(gui, selectmode = MULTIPLE, height = 5) + +for tmp_class in classes: + listbox.insert("end",tmp_class) + +def sel_class(flag = 1): + global filter, listbox, classes, cur_stu, students + filter.clear() + for selection in listbox.curselection(): + # print(selection) + filter.append(classes[selection]) + # print(filter) + if filter: + if flag: + msgbox.showinfo('班级选择已应用', '已应用当前班级选择', parent=gui) + cur_stu.clear() + for student in students: + if student.class_name in filter: + # print(student.name) + cur_stu.append(student) + else: + if flag: + msgbox.showwarning('班级选择已应用', '当前设置会选择所有班级的名单,这样对吗?', parent=gui) + filter = classes[:] + cur_stu = students[:] + +def choose(): + global last_choice, cur_stu + sel_class(0) + # 触发30%概率,从up中挑选 + if (random.randint(1,100) < up_percent and percent_override): + protection_override = True; + temp = [] + for student in cur_stu: + if int(float(student.id)) in up_id: + temp.append(student) + cur_stu = temp[:] + elif (random.randint(1,100) < down_persent and percent_override): + protection_override = True; + temp = []; + for student in cur_stu: + if int(float(student.id)) not in down_id: + temp.append(student) + cur_stu = temp[:] + else: + protection_override = False + + if not cur_stu: + protection_override = False + sel_class(0) + + choice = random.choice(cur_stu) + # print(choice.name) + counter = 0; + while (last_choice == choice.name and (not protection_override)) or choice.id in elim_id: + choice = random.choice(cur_stu) + counter = counter + 1 + if counter >= 100: + break + # print(choice.name) + upd_name(choice.name) + class_label.config(text = choice.class_name) + subject_label.config(text = choice.subject) + last_choice = choice.name + +startrandom = Button(gui, text = "立刻摇人!", font = ("宋体", 17, "bold"), height = 2, fg = "red", command = choose, bg = "white") + +setclass = Button(gui, text = "应用班级选用", font = ("宋体", 17), height = 2, command = sel_class, bg = "white") + +name_label = Label(gui, textvariable = cur_name, font = ("宋体", 30, "bold"), width = 20, bg = "white", fg = "blue") +class_label = Label(gui, text = "", font = ("宋体", 15), width = 20, bg = "white") +subject_label = Label(gui, text = "", font = ("宋体", 15), width = 20, bg = "white") + +class_label.grid(row = 2, column = 1, sticky = N+S+E+W) +subject_label.grid(row = 2, column = 2, sticky = N+S+E+W) +name_label.grid(row = 1, column = 1, sticky = N+S) +listbox.grid(row = 1, column = 2, sticky = N+S) +startrandom.grid(row = 3, column = 1, sticky = N+S+E+W) +setclass.grid(row = 3, column = 2, sticky = N+S+E+W) + +gui.mainloop() \ No newline at end of file