zhblue / hustoj

Popular Open Source Online Judge based on PHP/C++/MySQL/Linux for ACM/ICPC and NOIP training, with easy installation. 开源OJ系统
http://www.hustoj.com/?cat=2
GNU General Public License v2.0
3.18k stars 759 forks source link

hustoj选择题生成器(生成题面以及三个数据文件) #1015

Open duo-liang opened 2 months ago

duo-liang commented 2 months ago

选择题生成器.zip


import tkinter as tk
from tkinter import messagebox

class Application(tk.Tk):
    def __init__(self):
        super().__init__()

        self.title("hustoj选择题生成工具(author:Duoliang)")

        self.num_questions = 0
        self.score_per_question1 =0
        self.create_widgets()
        self.center_window()

    def create_widgets(self):
        # 设置窗口大小
        self.geometry("630x400")

        # 输入框
        self.label1 = tk.Label(self, text="题目数量:")
        self.label1.place(relx=0.1, y=20, anchor="w")
        self.entry_num_questions = tk.Entry(self, width=40)
        self.entry_num_questions.place(relx=0.3, y=20, anchor="w")

        self.label2 = tk.Label(self, text="题目名称:")
        self.label2.place(relx=0.1, y=60, anchor="w")
        self.entry_question_name = tk.Entry(self, width=40)
        self.entry_question_name.place(relx=0.3, y=60, anchor="w")

        self.label3 = tk.Label(self, text="正确答案:")
        self.label3.place(relx=0.1, y=100, anchor="w")
        self.entry_correct_answer = tk.Entry(self, width=40)
        self.entry_correct_answer.place(relx=0.3, y=100, anchor="w")

        self.label4 = tk.Label(self, text="选项A:")
        self.label4.place(relx=0.1, y=140, anchor="w")
        self.entry_option_a = tk.Entry(self, width=40)
        self.entry_option_a.place(relx=0.3, y=140, anchor="w")

        self.label5 = tk.Label(self, text="选项B:")
        self.label5.place(relx=0.1, y=180, anchor="w")
        self.entry_option_b = tk.Entry(self, width=40)
        self.entry_option_b.place(relx=0.3, y=180, anchor="w")

        self.label6 = tk.Label(self, text="选项C:")
        self.label6.place(relx=0.1, y=220, anchor="w")
        self.entry_option_c = tk.Entry(self, width=40)
        self.entry_option_c.place(relx=0.3, y=220, anchor="w")

        self.label7 = tk.Label(self, text="选项D:")
        self.label7.place(relx=0.1, y=260, anchor="w")
        self.entry_option_d = tk.Entry(self, width=40)
        self.entry_option_d.place(relx=0.3, y=260, anchor="w")

        # 状态显示框
        self.label_status = tk.Label(self, text="已生成的题目数量: 0")
        self.label_status.place(relx=0.5, y=320, anchor="center")

        # 按钮
        self.button_new = tk.Button(self, text="新建题单", command=self.create_new_questionnaire, width=15)
        self.button_new.place(relx=0.3, y=360, anchor="center")

        self.button_generate = tk.Button(self, text="生成题目", command=self.generate_question, width=15)
        self.button_generate.place(relx=0.7, y=360, anchor="center")

    def center_window(self):
        self.update_idletasks()
        screen_width = self.winfo_screenwidth()
        screen_height = self.winfo_screenheight()
        window_width = self.winfo_reqwidth()
        window_height = self.winfo_reqheight()
        x = (screen_width - window_width) // 3
        y = (screen_height - window_height) // 3
        self.geometry(f"630x400+{x}+{y}")

    def create_new_questionnaire(self):
        num_questions = self.entry_num_questions.get()

        try:
            num_questions = int(num_questions)
            if num_questions <= 0:
                messagebox.showerror("错误", "请输入一个正整数")
                return
        except ValueError:
            messagebox.showerror("错误", "请输入一个正整数")
            return

        self.num_questions = num_questions
        self.label_status.config(text=f"已生成的题目数量: 0")

        # 创建空白文件
        with open("problem.txt", "w") as f:
            f.write('<span class="auto_select">\n')

        with open("data.out", "w"):
            pass

        with open("template.c", "w") as f:
            pass

        with open("data.in", "w") as f:
            f.write(str(num_questions))

        #计算每题分数
        self.score_per_question1 = int(100 / self.num_questions)

        messagebox.showinfo("成功", "题单已创建")

    def generate_question(self):
        if self.num_questions == 0:
            messagebox.showerror("错误", "请先创建题单")
            return

        if self.num_questions == int(self.label_status.cget("text").split(": ")[-1]):
            messagebox.showinfo("生成结束", "题目已全部生成")
            with open("problem.txt", "a") as f:
                f.write('</span>')
            self.generate_data_out()
            self.generate_template_c()
            return

        # 更新状态显示框
        current_num = int(self.label_status.cget("text").split(": ")[-1]) + 1
        self.label_status.config(text=f"已生成的题目数量: {current_num}")

        # 写文件到data.out
        if current_num<self.num_questions :
            with open("data.out", "a") as f:
                f.write(f"{current_num} [{self.score_per_question1}] {self.entry_correct_answer.get()}\n")

        # 写入问题到文件
        with open("problem.txt", "a") as f:
            f.write(f"{current_num}. {self.entry_question_name.get()}( ).\n")
            f.write("<div>\n")
            f.write(f"A. {self.entry_option_a.get()}\n</div>\n")
            f.write("<div>\n")
            f.write(f"B. {self.entry_option_b.get()}\n</div>\n")
            f.write("<div>\n")
            f.write(f"C. {self.entry_option_c.get()}\n</div>\n")
            f.write("<div>\n")
            f.write(f"D. {self.entry_option_d.get()}\n</div>\n")
            f.write("<div>\n<p>\n</p>\n</div>\n")

        if self.num_questions == int(self.label_status.cget("text").split(": ")[-1]):
            messagebox.showinfo("生成结束", "题目已全部生成")
            with open("problem.txt", "a") as f:
                f.write('</span>')
            self.generate_data_out()
            self.generate_template_c()
            return

    def generate_data_out(self):
        score_per_question = int(100 / self.num_questions)
        total_score = 0

        for i in range(1, self.num_questions + 1):
            total_score += score_per_question

        # 调整最后一题的得分以确保总分之和为100

        last_question_score = score_per_question + (100 - total_score)
        with open("data.out", "a") as f:
            f.write(f"{self.num_questions} [{last_question_score}] {self.entry_correct_answer.get()}\n")

    def generate_template_c(self):
        with open("template.c", "w") as f:
            for i in range(1, self.num_questions + 1):
                f.write(f"{i}\n")

if __name__ == "__main__":
    app = Application()
    app.mainloop()
zhblue commented 2 months ago

感谢分享!