In this tutorial, we’ll create StudentMarks Sentinel, an AI-powered tool to predict student marks based on study hours, attendance, and previous scores. We’ll use Python, Tkinter for the GUI, and Scikit-Learn for machine learning.
You can clone the full code here: GitHub link
Step 1: Setup Your Project
First, create a new folder for your project and install the required packages:
pip install pandas numpy scikit-learn ttkbootstrap
We’ll use:
pandas and numpy for data handling
scikit-learn for machine learning
ttkbootstrap to make a modern Tkinter UI
Step 2: Import Required Libraries
At the top of your Python script, import the libraries we’ll need:
import os, sys, threading
import tkinter as tk
from tkinter import filedialog, messagebox
from tkinter import ttk
import pandas as pd
import numpy as np
import ttkbootstrap as tb
from ttkbootstrap.constants import *
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
Explanation:
tkinter → GUI elements like windows, buttons, and labels
pandas → handles CSV datasets
sklearn → train ML models
ttkbootstrap → gives your app a modern theme
Step 3: Define a Helper Function
We’ll create a small utility to handle file paths, which is helpful if we package our app later:
def resource_path(file_name):
base_path = getattr(sys, "_MEIPASS", os.path.dirname(os.path.abspath(__file__)))
return os.path.join(base_path, file_name)
Explanation:
Ensures your app can find files like icons whether it’s run normally or as an executable.
Step 4: Create the ML Worker
The ML worker will handle training the model in a separate thread to keep the UI responsive.
class MarksModelWorker:
def __init__(self, csv_path, callbacks):
self.csv_path = csv_path
self.callbacks = callbacks
self.model = LinearRegression()
def run(self):
try:
df = pd.read_csv(self.csv_path)
# Columns expected in CSV
X = df[["StudyHours", "Attendance", "PreviousMarks"]]
y = df["FinalMarks"]
# Split data into training and testing
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42
)
self.model.fit(X_train, y_train)
score = self.model.score(X_test, y_test)
if "trained" in self.callbacks:
self.callbacks["trained"](score, self.model)
except Exception as e:
if "error" in self.callbacks:
self.callbacks["error"](str(e))
Explanation:
LinearRegression → Predicts numeric marks
train_test_split → Splits data for testing accuracy
callbacks → Functions called after training or on error
Step 5: Build the GUI App
Now let’s start building the main app using Tkinter with ttkbootstrap:
class StudentMarksApp:
APP_NAME = "StudentMarks Sentinel"
APP_VERSION = "1.0"
def __init__(self):
self.root = tb.Window(themename="darkly")
self.root.title(f"{self.APP_NAME} v{self.APP_VERSION}")
self.root.minsize(1100, 650)
try:
self.root.iconbitmap(resource_path("logo.ico"))
except:
pass
self.model = None
self._build_ui()
Explanation:
Creates a main window with a modern dark theme
Sets minimum size and optional icon
_build_ui() will add all buttons, labels, and inputs
Step 6: Create the UI
We break the UI into sections:
6.1 Header
main = tb.Frame(self.root, padding=10)
main.pack(fill=tk.BOTH, expand=True)
tb.Label(
main,
text="🎓 StudentMarks Sentinel",
font=("Segoe UI", 22, "bold")
).pack(pady=(0, 4))
tb.Label(
main,
text="AI-Powered Student Marks Prediction",
font=("Segoe UI", 10, "italic"),
foreground="#9ca3af"
).pack(pady=(0, 20))
Explanation:
Adds the title and subtitle
6.2 Dataset Loader
row1 = tb.Frame(main)
row1.pack(fill=tk.X, pady=6)
self.dataset_entry = tb.Entry(row1, width=90)
self.dataset_entry.pack(side=tk.LEFT, fill=tk.X, expand=True, padx=(0, 6))
self.dataset_entry.insert(
0,
"Load CSV dataset (StudyHours, Attendance, PreviousMarks, FinalMarks)"
)
tb.Button(row1, text="📂 Load Dataset", bootstyle=INFO, command=self.load_dataset).pack(side=tk.LEFT, padx=3)
tb.Button(row1, text="🧠 Train Model", bootstyle=SUCCESS, command=self.train_model).pack(side=tk.LEFT, padx=3)
Explanation:
Text input to select CSV file
Buttons to load CSV and train ML model
Step 7: Add Prediction Inputs
form = tb.Labelframe(main, text="Marks Prediction", padding=15)
form.pack(fill=tk.X, pady=10)
self.study_var = tk.DoubleVar()
self.attendance_var = tk.DoubleVar()
self.prev_marks_var = tk.DoubleVar()
tb.Label(form, text="Study Hours / Day").grid(row=0, column=0, padx=5, pady=5)
tb.Entry(form, textvariable=self.study_var).grid(row=0, column=1, padx=5)
tb.Label(form, text="Attendance (%)").grid(row=0, column=2, padx=5)
tb.Entry(form, textvariable=self.attendance_var).grid(row=0, column=3, padx=5)
tb.Label(form, text="Previous Marks").grid(row=0, column=4, padx=5)
tb.Entry(form, textvariable=self.prev_marks_var).grid(row=0, column=5, padx=5)
tb.Button(form, text="📊 Predict Marks", bootstyle=PRIMARY, command=self.predict_marks).grid(row=0, column=6, padx=10)
Explanation:
Users can input their study hours, attendance, and previous marks
Press the button to predict final marks
Step 8: Implement Button Actions
def load_dataset(self):
path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
if path:
self.dataset_entry.delete(0, tk.END)
self.dataset_entry.insert(0, path)
def train_model(self):
path = self.dataset_entry.get()
if not os.path.isfile(path):
messagebox.showerror("Error", "Invalid dataset path")
return
self.stats_label.config(text="Training model...")
threading.Thread(target=self._train_worker, args=(path,), daemon=True).start()
Explanation:
load_dataset() → Opens a file dialog to select CSV
train_model() → Starts training in a separate thread
Step 9: Make Predictions
def predict_marks(self):
if not self.model:
messagebox.showwarning("Model", "Train the model first")
return
X = pd.DataFrame([{
"StudyHours": self.study_var.get(),
"Attendance": self.attendance_var.get(),
"PreviousMarks": self.prev_marks_var.get()
}])
marks = self.model.predict(X)[0]
self.result_label.config(text=f"Predicted Final Marks: {marks:.2f}")
Explanation:
Converts inputs into a DataFrame
Uses the trained model to predict marks
Updates label with predicted marks
Step 10: Run the App
Finally, add this to launch the app:
if __name__ == "__main__":
app = StudentMarksApp()
app.run()
✅ Congratulations!
You now have a full Student Marks Prediction app with a modern Tkinter UI and ML backend.
Next Steps:
Experiment with different ML algorithms like RandomForest
Add data validation for inputs
Save predictions to a CSV for record-keeping
GitHub: Clone the full project

Top comments (0)