In this tutorial, we’ll build HeartPredictor v2.0, a simple app that predicts heart disease risk using machine learning. Even if you’re a beginner, I’ll break it down into small sections with clear explanations.
You can clone the full project here: GitHub Link
Step 1: Install Required Libraries
We’ll use several Python packages:
pip install numpy pandas scikit-learn tkinter ttkbootstrap
Explanation:
numpy & pandas for data handling
scikit-learn for machine learning
tkinter & ttkbootstrap for building a GUI
Step 2: Import Modules
Start your Python file by importing all necessary modules:
import os, sys, threading, csv, numpy as np, pandas as pd
import tkinter as tk
from tkinter import filedialog, messagebox, ttk
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler
from sklearn.model_selection import train_test_split
import ttkbootstrap as tb
from ttkbootstrap.constants import *
Explanation:
These modules cover file operations, GUI components, and machine learning.
Step 3: Create a Helper Function
We need a helper function to access resources, especially when packaging the app:
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:
This function ensures your app can find files even when converted to an executable with tools like PyInstaller.
Step 4: Build the Heart Disease Model
We’ll use a simple logistic regression model. For now, we create a dummy dataset for demonstration.
class HeartDiseaseModel:
def __init__(self):
self.model = LogisticRegression(max_iter=1000)
self.scaler = StandardScaler()
self.features = ["age","sex","cp","trestbps","chol","fbs","restecg",
"thalach","exang","oldpeak","slope","ca","thal"]
self._train_dummy_model()
def _train_dummy_model(self):
np.random.seed(42)
X = np.random.randint(0, 100, size=(500, len(self.features)))
y = np.random.randint(0, 2, size=(500,))
X_scaled = self.scaler.fit_transform(X)
self.model.fit(X_scaled, y)
Explanation:
LogisticRegression predicts probabilities of heart disease.
StandardScaler normalizes the data.
_train_dummy_model() creates random data to train the model. Later, you can replace this with real patient data.
Step 5: Predict Risk
We need a function to classify risk levels:
def predict_risk(self, patient_data):
try:
x = np.array([float(patient_data.get(f,0)) for f in self.features]).reshape(1,-1)
x_scaled = self.scaler.transform(x)
prob = self.model.predict_proba(x_scaled)[0][1]
if prob < 0.33:
return "Low"
elif prob < 0.66:
return "Medium"
else:
return "High"
except Exception:
return "Low"
Explanation:
Converts patient info into a format the model can read
Uses probability thresholds to classify Low, Medium, High risk
Step 6: Create a Worker for Batch Prediction
We’ll handle multiple CSV files at once with a threaded worker:
class PredictionWorker:
def __init__(self, files, model, callbacks):
self.files = files
self.model = model
self._running = True
self.callbacks = callbacks
def run(self):
results = []
for path in self.files:
df = pd.read_csv(path)
for _, row in df.iterrows():
patient_data = row.to_dict()
name = patient_data.get("name","Unknown")
risk = self.model.predict_risk(patient_data)
results.append((path, name, risk))
if "found" in self.callbacks:
self.callbacks["found"](path, name, risk)
if "finished" in self.callbacks:
self.callbacks["finished"]()
Explanation:
Reads CSV files
Sends results to the GUI using callbacks
Allows batch processing without freezing the interface
Step 7: Build the GUI
We’ll use Tkinter + TTKBootstrap for a modern look:
class HeartPredictorApp:
def __init__(self):
self.root = tb.Window(themename="darkly")
self.root.title("HeartPredictor v2.0")
self.root.minsize(1000, 600)
self.model = HeartDiseaseModel()
self._build_ui()
Explanation:
tb.Window() creates a themed window
We initialize the model
_build_ui() will create buttons, file selectors, and the progress bar
Add File Selection and Buttons
self.path_input = tb.Entry(row1, width=80)
self.path_input.pack(side=LEFT, fill=X, expand=True)
browse_btn = tb.Button(row1, text="📂 Browse", bootstyle=INFO, command=self.browse)
browse_btn.pack(side=LEFT, padx=3)
self.start_btn = tb.Button(row1, text="🚀 Start Prediction", bootstyle=SUCCESS, command=self.start)
self.start_btn.pack(side=LEFT, padx=3)
Explanation:
Entry: Shows selected CSV files
Browse: Opens file dialog
Start Prediction: Runs the worker thread
Step 8: Display Results in a Table
columns = ("selected", "filename", "patient", "risk")
self.tree = ttk.Treeview(main, columns=columns, show="headings")
self.tree.heading("filename", text="Filename")
self.tree.heading("patient", text="Patient Name")
self.tree.heading("risk", text="Predicted Risk")
self.tree.pack(fill=BOTH, expand=True)
Explanation:
Treeview displays results in rows and columns
Columns show filename, patient name, and risk level
Step 9: Add Export Functionality
def export_results(self):
path = filedialog.asksaveasfilename(defaultextension=".csv")
with open(path,"w",newline='') as f:
writer = csv.writer(f)
writer.writerow(["Filename","Patient Name","Predicted Risk"])
for i in self.tree.get_children():
row = self.tree.item(i)['values']
writer.writerow([row[1], row[2], row[3]])
Explanation:
Allows exporting predictions to a CSV file for easy sharing
Step 10: Run the App
Finally, we run the application:
if __name__ == "__main__":
app = HeartPredictorApp()
app.run()
Explanation:
Initializes the GUI and starts the main loop
Now you can browse CSV files, predict risks, and export results
Conclusion
Congratulations! 🎉
You now have a Heart Disease Prediction app with a modern GUI and batch processing. You can improve it by:
Using real patient data
Adding more machine learning models
Visualizing risk statistics
Clone the full project here: https://github.com/rogers-cyber/python-tiny-tools/tree/main/Heart-disease-prediction-app

Top comments (0)