Skip to content

Commit 6b22978

Browse files
authored
Create BodyMetrics_Pro.py
1 parent 35cfa51 commit 6b22978

1 file changed

Lines changed: 205 additions & 0 deletions

File tree

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
"""
2+
BodyMetrics Pro v2.0 - Health Intelligence Edition
3+
ML-Powered BMI Risk Prediction System
4+
Age • Gender • AI Risk Scoring • Visual Analytics
5+
"""
6+
7+
import tkinter as tk
8+
from tkinter import messagebox
9+
import ttkbootstrap as tb
10+
from ttkbootstrap.constants import *
11+
12+
import numpy as np
13+
from sklearn.linear_model import LogisticRegression
14+
from sklearn.preprocessing import StandardScaler
15+
16+
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
17+
from matplotlib.figure import Figure
18+
19+
20+
# ---------------------- ML ENGINE ----------------------
21+
class BMIRiskModel:
22+
def __init__(self):
23+
self.scaler = StandardScaler()
24+
self.model = LogisticRegression()
25+
self._train()
26+
27+
def _train(self):
28+
# Synthetic training data: [BMI, Age, Gender]
29+
# Gender: Male=1, Female=0
30+
X = np.array([
31+
[18, 18, 0], [22, 25, 1], [24, 30, 0],
32+
[27, 40, 1], [29, 45, 0], [32, 50, 1],
33+
[35, 55, 0], [38, 60, 1], [42, 65, 0]
34+
])
35+
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2]) # Risk levels
36+
37+
X_scaled = self.scaler.fit_transform(X)
38+
self.model.fit(X_scaled, y)
39+
40+
def predict(self, bmi, age, gender):
41+
X = np.array([[bmi, age, gender]])
42+
X_scaled = self.scaler.transform(X)
43+
return self.model.predict(X_scaled)[0]
44+
45+
46+
# ---------------------- UTIL ----------------------
47+
def calculate_bmi(weight, height):
48+
return round(weight / (height ** 2), 2)
49+
50+
51+
def risk_label(code):
52+
return {
53+
0: ("Low Risk", "✅"),
54+
1: ("Moderate Risk", "⚠️"),
55+
2: ("High Risk", "❌")
56+
}[code]
57+
58+
59+
# ---------------------- MAIN APP ----------------------
60+
class BMIPredictorApp:
61+
APP_NAME = "BodyMetrics Pro"
62+
APP_VERSION = "2.0"
63+
64+
def __init__(self):
65+
self.root = tb.Window(themename="darkly")
66+
self.root.title(f"{self.APP_NAME} v{self.APP_VERSION}")
67+
self.root.minsize(720, 620)
68+
69+
self.model = BMIRiskModel()
70+
71+
self._build_ui()
72+
73+
# ---------------------- UI ----------------------
74+
def _build_ui(self):
75+
main = tb.Frame(self.root, padding=15)
76+
main.pack(fill=BOTH, expand=True)
77+
78+
tb.Label(
79+
main,
80+
text=f"🧠 {self.APP_NAME}",
81+
font=("Segoe UI", 22, "bold")
82+
).pack()
83+
84+
tb.Label(
85+
main,
86+
text="ML-Based BMI Risk Prediction System",
87+
font=("Segoe UI", 10, "italic"),
88+
foreground="#9ca3af"
89+
).pack(pady=(0, 20))
90+
91+
# ---------------------- INPUT PANEL ----------------------
92+
form = tb.Labelframe(main, text="Personal Data", padding=15)
93+
form.pack(fill=X, pady=10)
94+
95+
self.weight = tb.Entry(form, width=15)
96+
self.height = tb.Entry(form, width=15)
97+
self.age = tb.Entry(form, width=15)
98+
99+
self.gender = tk.StringVar(value="Male")
100+
101+
labels = ["Weight (kg)", "Height (m)", "Age"]
102+
entries = [self.weight, self.height, self.age]
103+
104+
for i, (l, e) in enumerate(zip(labels, entries)):
105+
tb.Label(form, text=l).grid(row=i, column=0, sticky=W, pady=5)
106+
e.grid(row=i, column=1, padx=10)
107+
108+
tb.Label(form, text="Gender").grid(row=3, column=0, sticky=W, pady=5)
109+
tb.Combobox(
110+
form,
111+
values=["Male", "Female"],
112+
textvariable=self.gender,
113+
width=13
114+
).grid(row=3, column=1)
115+
116+
# ---------------------- ACTIONS ----------------------
117+
tb.Button(
118+
main,
119+
text="🚀 Analyze Health Risk",
120+
bootstyle=SUCCESS,
121+
command=self.analyze
122+
).pack(pady=10)
123+
124+
self.progress = tb.Progressbar(
125+
main,
126+
bootstyle="success-striped",
127+
maximum=100
128+
)
129+
self.progress.pack(fill=X, pady=5)
130+
131+
# ---------------------- RESULT ----------------------
132+
self.result = tb.Label(
133+
main,
134+
text="Awaiting input...",
135+
font=("Segoe UI", 14)
136+
)
137+
self.result.pack(pady=10)
138+
139+
# ---------------------- CHART ----------------------
140+
chart_frame = tb.Labelframe(main, text="BMI Visualization", padding=10)
141+
chart_frame.pack(fill=BOTH, expand=True)
142+
143+
self.figure = Figure(figsize=(5, 3))
144+
self.ax = self.figure.add_subplot(111)
145+
self.canvas = FigureCanvasTkAgg(self.figure, chart_frame)
146+
self.canvas.get_tk_widget().pack(fill=BOTH, expand=True)
147+
148+
# ---------------------- LOGIC ----------------------
149+
def analyze(self):
150+
try:
151+
self.progress["value"] = 0
152+
self.root.update_idletasks()
153+
154+
w = float(self.weight.get())
155+
h = float(self.height.get())
156+
age = int(self.age.get())
157+
gender = 1 if self.gender.get() == "Male" else 0
158+
159+
if w <= 0 or h <= 0 or age <= 0:
160+
raise ValueError
161+
162+
self.progress["value"] = 30
163+
164+
bmi = calculate_bmi(w, h)
165+
self.progress["value"] = 60
166+
167+
risk_code = self.model.predict(bmi, age, gender)
168+
label, icon = risk_label(risk_code)
169+
170+
self.progress["value"] = 100
171+
172+
self.result.config(
173+
text=f"{icon} BMI: {bmi} | {label}",
174+
font=("Segoe UI", 16, "bold")
175+
)
176+
177+
self._update_chart(bmi)
178+
179+
except Exception:
180+
messagebox.showerror(
181+
"Invalid Input",
182+
"Please enter valid numeric values."
183+
)
184+
self.progress["value"] = 0
185+
186+
# ---------------------- CHART ----------------------
187+
def _update_chart(self, bmi):
188+
self.ax.clear()
189+
self.ax.bar(["Your BMI"], [bmi])
190+
self.ax.axhline(18.5, linestyle="--")
191+
self.ax.axhline(25, linestyle="--")
192+
self.ax.axhline(30, linestyle="--")
193+
self.ax.set_ylabel("BMI Value")
194+
self.ax.set_title("BMI Classification Zones")
195+
self.canvas.draw()
196+
197+
# ---------------------- RUN ----------------------
198+
def run(self):
199+
self.root.mainloop()
200+
201+
202+
# ---------------------- RUN ----------------------
203+
if __name__ == "__main__":
204+
app = BMIPredictorApp()
205+
app.run()

0 commit comments

Comments
 (0)