DEV Community

Mate Technologies
Mate Technologies

Posted on

Build a Heart Disease Prediction App with Python and Tkinter

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 *
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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"
Enter fullscreen mode Exit fullscreen mode

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"]()
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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]])
Enter fullscreen mode Exit fullscreen mode

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()
Enter fullscreen mode Exit fullscreen mode

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

MachineLearning #Python #Tkinter #HealthTech #DataScience #AI #HeartDisease #OpenSource #BeginnerFriendly

Top comments (0)