SoFunction
Updated on 2024-11-16

Multi-functional Classroom Roll Caller and Lottery Tool Using Python

I. Origin of the problem

Last year, the wave of ChatGPT hit, I know simple basic Python syntax and have some ideas, so with the help of AI quiz tool, step by step, I made a namer, which can also be used for drawing lots. At that time, I had already designed the page and basic functions, and opened the test in the general public.

Roll Call 1.0

At present, the article written about this namer has reached nearly 700 times in the reading, and there are 6 people collection, which shows that a lot of people still need such a namer. However, there are some users leave me a message, put forward the suggestion of modification, such as the interface of the namer is a little big, sometimes used in the teaching process, sometimes not used, used when you can show, not used, can you minimize the interface to the upper right corner, and then click the upper right corner to bring it out.

Someone else said that if the person was drawn, could they read out their name as well so that the teacher wouldn't have to say their name again. When they hear the voice and see their name, the student can stand up and answer the question directly, and the teacher won't have to read the student's name again.

FYI: At that time, I just learned Python on my own, mainly by reading Dong Fuguo's book, which is easy to understand and very informative, with all the important points covered. I read the following book:

Just knew some basic syntax, but with the addition of AI, I quickly learned to program autonomously.

Before, I have been busy with other things and didn't take the time to do so, but now that I've used the help of ChatGPT, I believe that it's not difficult to do some small project development using Python.

II. Development process

1. Add maximize and minimize function to the roll caller

First of all, my modifications and upgrades to the original roll caller were based on the first version, and the two features I needed to add were read aloud and minimize.

Ask ChatGPT a question

ChatGPT quickly gave me the appropriate code based on my request:

import tkinter as tk
 
class MinimizeApp:
    def __init__(self, master):
         = master
        ("800x600")  # Initial size
         = False  # Whether the marker is minimized
        self.original_geometry = ''  # Store the original window size
        
        # Minimize/Maximize buttons
        self.toggle_btn = (master, text="Minimize.", command=)
        self.toggle_btn.pack()
 
        # Configure a small window to display when minimized
        self.mini_window = ()
        self.mini_window.geometry("100x50+{}+0".format(.winfo_screenwidth() - 100))
        self.mini_window.overrideredirect(True)  # Remove window borders
        self.mini_window.withdraw()  # Initially hidden
 
        # Maximize button
        self.maximize_btn = (self.mini_window, text="Maximize.", command=)
        self.maximize_btn.pack(fill=, expand=True)
 
    def toggle(self):
        if :  # If currently minimized, restore window
            ()  # Show main window
            (self.original_geometry)  # Restore original size
            self.mini_window.withdraw()  # Hide minimized windows
            self.toggle_btn.config(text="Minimize.")
             = False
        else:  # Minimize the window if it is currently normal size
            self.original_geometry = ()  # Store the current size and position
            ()  # Hide the main window
            self.mini_window.deiconify()  # Show minimized windows
             = True
 
def main():
    root = ()
    app = MinimizeApp(root)
    ()
 
if __name__ == "__main__":
    main()

The above code implements a custom minimize/maximize function by first creating a minimize button, when the user clicks on this button, the entire application window shrinks to the top right corner of the screen and only a maximize button is displayed. When this maximize button is clicked again, the window returns to its original size.

We manage the size and position of the window, as well as the showing and hiding of the buttons, by manually clicking on them.

The next step is to take the above code and incorporate it into Roll Call 1.0, where we need to change the names of the button objects, remove duplicate code compared to the old version, and also fix the errors reported during debugging.

During the course of the lesson, I conducted another field test and found that the minimized window pins were not placed at the front of all the windows, so I asked ChatGPT if I could set up the minimized window to show at the front of the window, and it quickly gave me the following code:

self.mini_window.attributes('-topmost', 1)

Sure enough, the front display problem was quickly solved with this code.

2. Adding a read-aloud function to the roll-caller

Added the ability to maximize and minimize the window, and I'd also like to have the roll caller automatically read aloud the name of the person on the roll caller, so that the name displayed matches the voice read aloud, which would maximize the possibility of saving the teacher's time and energy, and further enhance the efficiency of the lecture.

In order to make the software audible, we need to import a pyttsx3 package and also make sure that the software is connected to the Internet.

When scrolling to the displayed person's name, it triggers the read-aloud function. Of course, there are people who don't want to use the read-aloud feature, or use computers that don't have access to the Internet, so we need to add a checkbox to control whether or not the read-aloud is vocalized using the checkbox.

I was able to ask ChatGPT a question and got the following response:

Add checkbox

The next thing I want to do is to add a checkbox code to the def __init__(self, master) initialization function, and control whether or not the sound is read aloud by checking the value of the checkbox check_var. Note that the checkbox does not need to be defined as a command function.

Finally, during testing, I noticed that the software was not reading people's names aloud, only to find out later that the initialization of = (), the vocalization engine, has to be started before the software interface is initialized.

3. Demonstration of software use

After modifying and testing at noon and in the afternoon, the prototype of the new version of the roll caller was finally completed, as shown in the picture below:

4. Optimized code

While adding the functions of reading aloud and minimizing, I solicited the opinions of the users and added the function of automatic adjustment of the name font. Moreover, in order to make the interface display better, I centered the button display and finally formed the following software.

The software code is as follows:

# 2023 April 10 update 1. fix button click start then click pause 2. add marker function 3. add welcome page 4. change playback speed
# Updated February 28, 2024 1. add people's names to be read aloud 2. add window minimization feature 3. button centering 4. font size control
import tkinter as tk
from tkinter import messagebox
from tkinter import ttk
import os
import random
import time
import pyttsx3
 
class RollCallApp:
    def __init__(self, master):
         = ()
         = master
        ("Roll Call Gordon QQ:403096966")
        #(False, False)
        #("880x300") # Initial size
         = False  # Whether the marker is minimized
        ("WM_DELETE_WINDOW", self.display_messagebox) # A pop-up prompt confirms the exit
        ('-topmost', True)
        # Read the names in the file
         = []
        self.load_names()
 
        # Controls that play names
        self.label_name = (, text="Welcome to the roll call.", font=("Times New Roman", 90), fg="blue")
        self.label_name.pack(pady=50)
        
        
        #Set the frame to be centered
        button_frame = ()
        button_frame.pack()
        items = ("Extra points.","Absenteeism.", "Late.", "Take a vacation.")
         = (button_frame, values=items, font=("Song Style", 20),width=5)
        ("Extra points.")  # Set default values
        (font=("Song Style", 20))
        #Set font capitalization
         = (, from_ = 30, to = 210, orient = 'horizontal',command = )
        (80)
        (expand=True, fill=,side=) 
        
        # Set up the exit button
        self.button_quit = (button_frame, text="Exit.", font=("Song Style", 20), width=9, command=self.display_messagebox)
        self.button_quit.pack(side=,anchor="center",padx=22)
        # Set the content of the markers
        (side=, fill=, padx=5)
        
        # Create an IntVar object to store the state of the checkboxes
        self.check_var = (value=0)  # Default value set to 0 (unchecked)
        
        # Control buttons
        self.button_mark = (button_frame, text="Marker.", font=("Song Style", 20), width=9, command=self.write_txt)
        self.button_mark.pack(side=,anchor="center",padx=20)
        
        # Create checkboxes, bind to check_var variable
         = (button_frame, text="Voices.", font=("Song Style", 12), variable=self.check_var)
        (side=,anchor="center", padx=3)
 
        # Control buttons
        self.button_action = (button_frame, text="Begin.", font=("Song Style", 20), width=9, command=self.toggle_rolling)
        self.button_action.pack(side=, anchor="center",padx=20)
 
        self.button_min = (button_frame, text="Minimize.", font=("Song Style", 20), width=9, command=)
        self.button_min.pack(side=,anchor="center", padx=20)
        
        # Configure a small window to display when minimized
        self.mini_window = ()
        self.mini_window.geometry("100x50+{}+0".format(.winfo_screenwidth() - 100))
        self.mini_window.overrideredirect(True)  # Remove window borders
        self.mini_window.withdraw()  # Initially hidden
 
        # Maximize button
        self.maximize_btn = (self.mini_window, text="Maximize.",font=("Song Style", 15, "bold"), command=)
        self.maximize_btn.pack(fill=, expand=True)
        
        # Control variables
         = False
        self.current_name = ""
        
        #Setup Engine
        ('language', 'zh-CN')
        rate = ('rate')
        ('rate', rate - 50)
        # Set the size of the articulation, in the range 0.0-1.0
        volume = ('volume')
        ('volume', 1.2)
        # Set default voices: voices[0].id for boys, voices[1].id for girls
        voices = ('voices')
        ('voice', voices[0].id)
    def resize(self,ev = None):
        # Monitor whether the window is maximized or not, if maximized then the font is bigger, otherwise it is 55 characters.
        if () == 'zoomed':
            self.label_name.config(font = 'Song -%d bold' % ())
        elif not () == 'zoomed':#() == 'iconic':
            self.label_name.config(font = 'Song -%d bold' % ())
        
    def toggle(self):
        if :  # If currently minimized, restore window
            ()  # Show main window
            #("880x300") # Initial size
            #(self.original_geometry) # restore original size
            self.mini_window.withdraw()  # Hide minimized windows
            self.button_min.config(text="Minimize.")
             = False
        else:  # Minimize the window if it is currently normal size
            self.original_geometry = ()  # Store the current size and position
            ()  # Hide the main window
            self.mini_window.deiconify()  # Show minimized windows
            self.mini_window.attributes('-topmost', 1)
             = True        
        
 
    def load_names(self):
        """Read names from files in the current directory."""
        if (""):
            with open("", "r", encoding="utf-8") as f:
                for name in f:
                    name = ()
                    if name:
                        (name)
        else:
            ("Error.","Can't find it, please put the name in the current directory!")
            with open("", "w+", encoding="utf-8") as fi:
                ("")
    def write_txt(self):
        label_text = self.label_name.cget("text")
        with open("Marked content.txt",'a+',encoding='utf-8') as f:
            (label_text + f" {()}\n")
 
    def toggle_rolling(self):
        """Toggles playback state and updates button text"""
         = not 
        if :
            self.button_action.config(text="Pause.")
            self.roll_name()
            if self.check_var.get() == 1:
                (self.current_name)
                ()
        else:
            self.button_action.config(text="Begin.")
 
    def roll_name(self):
        """Randomly pick a name to play."""
 
        if :
            self.current_name = ()
            self.label_name.config(text=self.current_name)
            ()
            (0.01)
            if :
                self.roll_name()
 
    def display_messagebox(self):
        """A pop-up window prompts whether to confirm exit from the program."""
        if ("Exit the program.", "Sure you want to get out of the program?"):
            ()
 
if __name__ == "__main__":
    root = ()
    app = RollCallApp(root)
    ()
 

III. Post-learning reflections

This software was originally written in April of last year, but in February of this year, I suddenly got a new inspiration and added two good features in a short time. It seems that it takes some time to polish the software. We are going to use ChatGPT to modify and upgrade the original software while taking the advice of users.

Python is the hottest programming language today, playing an irreplaceable role in the field of artificial intelligence. It is extremely scalable and flexible, can realize cross-platform applications, and is widely used in web development, web crawlers, office automation and other fields. Therefore, to bring great convenience to your work and life, I suggest you learn this popular language as early as possible. With the empowerment of ChatGPT, everyone can borrow for videos and books to learn it easily.

Above is the use of Python to realize a multi-functional classroom roll caller and lottery tool in detail, more information about Python roll caller please pay attention to my other related articles!