DEV Community

Mate Technologies
Mate Technologies

Posted on

๐Ÿท Building WineSense v1.0 โ€“ A Beginner-Friendly Machine Learning App in Python

In this step-by-step tutorial, weโ€™ll build WineSense, a desktop application that predicts wine quality using Machine Learning and a clean Tkinter GUI.

This guide is written for beginners and breaks everything into small, easy-to-understand steps.

๐Ÿš€ What Youโ€™ll Build

By the end of this tutorial, you will have:

A Machine Learning model trained on wine data

A desktop app with a modern dark UI

A button to train the model from a CSV file

A form to enter wine properties

Instant wine quality predictions

๐Ÿงฐ Technologies Used

Python

Pandas & NumPy

Scikit-learn (Random Forest)

Tkinter + ttkbootstrap

๐Ÿ“ Project Structure
Wine-quality-prediction-app/
โ”‚
โ”œโ”€โ”€ app.py
โ”œโ”€โ”€ winequality.csv
โ”œโ”€โ”€ requirements.txt
๐Ÿ“ฆ Step 1: Install Dependencies

Create a virtual environment (optional but recommended), then install dependencies:

pip install pandas numpy scikit-learn ttkbootstrap
๐Ÿง  Step 2: Creating the Machine Learning Model

We start by defining a class that will:

Load a CSV file

Train a model

Make predictions

2.1 Import Required Libraries

import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
Enter fullscreen mode Exit fullscreen mode

2.2 Define the Model Class

class WineQualityModel:
    def __init__(self):
        self.model = RandomForestClassifier(n_estimators=200, random_state=42)
        self.trained = False
        self.accuracy = 0.0
        self.feature_names = []

Enter fullscreen mode Exit fullscreen mode

๐Ÿ” Explanation:

RandomForestClassifier is robust and beginner-friendly

trained ensures predictions arenโ€™t made before training

2.3 Training the Model

    def train(self, csv_path):
        data = pd.read_csv(csv_path)


        if 'quality' not in data.columns:
            raise ValueError("CSV must contain a 'quality' column")


        self.feature_names = [c for c in data.columns if c != 'quality']
        X = data[self.feature_names]
        y = data['quality']


        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)
        preds = self.model.predict(X_test)
        self.accuracy = accuracy_score(y_test, preds)
        self.trained = True
Enter fullscreen mode Exit fullscreen mode

๐Ÿ“Œ Whatโ€™s happening here?

Load CSV

Separate features and labels

Train the model

Measure accuracy

2.4 Making Predictions

    def predict(self, features):
        if not self.trained:
            raise RuntimeError("Model not trained")


        X = pd.DataFrame([features], columns=self.feature_names)
        return int(self.model.predict(X)[0])
Enter fullscreen mode Exit fullscreen mode

โœ… We wrap inputs in a DataFrame so Scikit-learn understands feature names.

๐Ÿ–ฅ Step 3: Building the GUI (Tkinter + ttkbootstrap)
3.1 Create the App Window

import ttkbootstrap as tb
from ttkbootstrap.constants import *


class WineSenseApp:
    def __init__(self):
        self.root = tb.Window(themename="darkly")
        self.root.title("WineSense v1.0")
        self.root.minsize(900, 600)


        self.model = WineQualityModel()
        self.feature_vars = {}
        self._build_ui()
Enter fullscreen mode Exit fullscreen mode

๐ŸŽจ ttkbootstrap gives us a modern dark theme with no extra styling effort.

3.2 App Header

tb.Label(
    main,
    text="๐Ÿท WineSense - Quality Prediction",
    font=("Segoe UI", 22, "bold")
).pack(pady=(0, 5))
Enter fullscreen mode Exit fullscreen mode

This creates a bold title at the top of the app.

๐Ÿ“Š Step 4: Training the Model from the UI
4.1 Training Button

tb.Button(
    train_frame,
    text="๐Ÿ“Š Load Wine CSV & Train Model",
    bootstyle=SUCCESS,
    command=self.train_model
).pack(side=LEFT, padx=5)
Enter fullscreen mode Exit fullscreen mode

4.2 Training Logic (Threaded)

import threading
from tkinter import filedialog


    def train_model(self):
        path = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")])
        if not path:
            return


        threading.Thread(target=self._train_thread, args=(path,), daemon=True).start()
Enter fullscreen mode Exit fullscreen mode

๐Ÿงต Why threading? So the UI doesnโ€™t freeze while training.

๐Ÿงช Step 5: Input Wine Features

We define the wine properties expected by the dataset:

self.features = [
    "fixed acidity",
    "volatile acidity",
    "citric acid",
    "residual sugar",
    "chlorides",
    "free sulfur dioxide",
    "total sulfur dioxide",
    "density",
    "pH",
    "sulphates",
    "alcohol",
]
Enter fullscreen mode Exit fullscreen mode

Each feature gets an input field using DoubleVar().

๐Ÿ”ฎ Step 6: Predict Wine Quality

    def predict_quality(self):
        if not self.model.trained:
            messagebox.showwarning("Model", "Please train the model first")
            return


        features = [self.feature_vars[f].get() for f in self.features]
        quality = self.model.predict(features)
        self.result_label.config(text=f"Quality: {quality}")
Enter fullscreen mode Exit fullscreen mode

๐ŸŽฏ Enter values โ†’ Click Predict โ†’ Get instant results.

โ–ถ Step 7: Run the App

if __name__ == "__main__":
    app = WineSenseApp()
    app.run()
Enter fullscreen mode Exit fullscreen mode

๐Ÿง  What You Learned

โœ” How to train an ML model in Python โœ” How to connect ML with a GUI โœ” How to handle CSV input โœ” How to build a real desktop ML app

๐Ÿ”— Source Code

GitHub Repository: https://github.com/rogers-cyber/python-tiny-tools/tree/main/Wine-quality-prediction-app

๐Ÿ™Œ Final Thoughts

This project is perfect for:

Beginners learning Machine Learning

Python developers exploring GUIs

Students building portfolio projects

Happy coding & cheers to smart wine ๐Ÿท

Iโ€™ve created a Dev.toโ€“style, step-by-step beginner tutorial in the canvas ๐Ÿ“˜

What this version does well

Breaks the project into clear learning stages

Uses small, focused code blocks instead of dumping the full script

Explains what and why after each block

Written in a friendly Dev.to tone suitable for beginners

Ready to publish with minimal editing

Top comments (0)