Konten Sub Menu "Indeks Massa Tubuh (IMT)
Isi Menu "Profil Kesehatan"
(Konten Sub Menu "Indeks Massa Tubuh (IMT)")
3. Sub Menu "Indeks Massa Tubuh (IMT)"
Lanjut kita membuat konten Sub Menu "Indeks Massa Tubuh (IMT)"
Baik! Mari kita lanjutkan membuat sub menu "Indeks Massa Tubuh (IMT)" sebagai bagian dari menu Profil Kesehatan.
๐ฏ Tujuan:
- Menampilkan form input berat badan (kg) dan tinggi badan (cm).
- Ketika tombol "Hitung IMT" ditekan:
- Menghitung IMT (BMI).
- Menampilkan hasil nilai IMT.
- Memberikan kategori IMT sesuai standar WHO.
- Menyediakan tombol "Kembali" ke Menu Profil Kesehatan.
✅ Kode Python – sub_menu_indeks_massa_tubuh.py
# sub_menu_indeks_massa_tubuh.pyimport tkinter as tkfrom tkinter import messageboxdef show_sub_menu_indeks_massa_tubuh(root_frame):from menu_profil_kesehatan import show_menu_profil_kesehatan # Hindari circular importfor widget in root_frame.winfo_children():widget.destroy()# Judullabel_judul = tk.Label(root_frame,text="Indeks Massa Tubuh (IMT)",font=("Arial", 18, "bold"),bg="green",fg="orange",padx=10,pady=10)label_judul.pack(pady=20)# Frame inputform_frame = tk.Frame(root_frame)form_frame.pack(pady=10)# Berat badantk.Label(form_frame, text="Berat Badan (kg):", font=("Arial", 12)).grid(row=0, column=0, sticky="w", padx=5, pady=5)entry_berat = tk.Entry(form_frame, font=("Arial", 12))entry_berat.grid(row=0, column=1, padx=5, pady=5)# Tinggi badantk.Label(form_frame, text="Tinggi Badan (cm):", font=("Arial", 12)).grid(row=1, column=0, sticky="w", padx=5, pady=5)entry_tinggi = tk.Entry(form_frame, font=("Arial", 12))entry_tinggi.grid(row=1, column=1, padx=5, pady=5)# Label hasillabel_hasil = tk.Label(root_frame, text="", font=("Arial", 12, "bold"), fg="blue")label_hasil.pack(pady=10)# Fungsi hitung IMTdef hitung_imt():try:berat = float(entry_berat.get())tinggi_cm = float(entry_tinggi.get())tinggi_m = tinggi_cm / 100imt = berat / (tinggi_m ** 2)imt = round(imt, 2)if imt < 18.5:kategori = "Kurus"elif 18.5 <= imt < 25:kategori = "Normal"elif 25 <= imt < 30:kategori = "Kelebihan Berat Badan"else:kategori = "Obesitas"label_hasil.config(text=f"IMT Anda: {imt} ({kategori})")except ValueError:messagebox.showerror("Input Tidak Valid", "Masukkan angka yang benar untuk berat dan tinggi badan.")# Tombol hitungtk.Button(root_frame,text="Hitung IMT",font=("Arial", 12),bg="blue",fg="white",command=hitung_imt).pack(pady=10)# Tombol kembalitk.Button(root_frame,text="Kembali",font=("Arial", 12),bg="gray",fg="white",command=lambda: show_menu_profil_kesehatan(root_frame)).pack(pady=20)
๐ง Langkah Selanjutnya:
- Tambahkan tombol baru di
menu_profil_kesehatan.py:
from sub_menu_indeks_massa_tubuh import show_sub_menu_indeks_massa_tubuhsubmenu_items = [("Data Diri", show_sub_menu_data_diri),("Berat & Tinggi Badan", show_sub_menu_berat_tinggi_badan),("Indeks Massa Tubuh (IMT)", show_sub_menu_indeks_massa_tubuh), # Tambahkan ini]
Siap untuk lanjut ke sub menu berikutnya atau integrasi database jika IMT ingin disimpan juga?
Gunakan data dari database ((data_diri.db) untuk menghitung IMT. Lalu tampilkan Data Berat Badan, dan Tinggi Badan, ketika mendapat hasil menghitung IMT.
Bagus, kita akan menggunakan data dari database SQLite data_diri.db untuk menghitung Indeks Massa Tubuh (IMT). Artinya, saat pengguna membuka sub menu IMT, aplikasi akan otomatis mengambil berat dan tinggi badan dari database lalu menghitung nilai IMT-nya.
---
✅ Asumsi Struktur Database
Nama database: /storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_diri.db
Nama tabel: data_diri
Kolom minimal: nama, usia, berat, tinggi
---
✅ Tujuan
Saat halaman IMT dibuka:
Ambil data berat dan tinggi dari database.
Hitung dan tampilkan IMT secara otomatis.
Tampilkan pesan jika data belum tersedia.
Kita akan modifikasi konten Sub Menu "Indeks Massa Tubuh (IMT)" agar:
✅ Menampilkan:
- Berat Badan
- Tinggi Badan
- Hasil Perhitungan IMT
- Kategori IMT
Semua ini diambil langsung dari database SQLite (data_diri.db).
✅ Revisi Kode sub_menu_indeks_massa_tubuh.py
Berikut kode lengkap yang sudah diperbarui:
# sub_menu_indeks_massa_tubuh.py
import tkinter as tk
from tkinter import messagebox
import sqlite3
import os
def show_sub_menu_indeks_massa_tubuh(root_frame):
from menu_profil_kesehatan import show_menu_profil_kesehatan # Hindari circular import
for widget in root_frame.winfo_children():
widget.destroy()
# Judul
label_judul = tk.Label(
root_frame,
text="Indeks Massa Tubuh (IMT)",
font=("Arial", 18, "bold"),
bg="green",
fg="orange",
padx=10,
pady=10
)
label_judul.pack(pady=20)
# Label data berat dan tinggi
label_berat = tk.Label(root_frame, text="", font=("Arial", 12))
label_berat.pack(pady=5)
label_tinggi = tk.Label(root_frame, text="", font=("Arial", 12))
label_tinggi.pack(pady=5)
# Label hasil IMT
label_hasil = tk.Label(root_frame, text="", font=("Arial", 12, "bold"), fg="blue")
label_hasil.pack(pady=10)
# Lokasi database
db_path = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_diri.db"
# Fungsi untuk ambil dan hitung IMT
def ambil_dan_hitung_imt():
if not os.path.exists(db_path):
label_hasil.config(text="Database tidak ditemukan.")
return
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("SELECT berat, tinggi FROM data_diri ORDER BY id DESC LIMIT 1")
data = cursor.fetchone()
conn.close()
if data is None:
label_hasil.config(text="Data belum tersedia.")
return
berat, tinggi = data
label_berat.config(text=f"Berat Badan: {berat} kg")
label_tinggi.config(text=f"Tinggi Badan: {tinggi} cm")
tinggi_m = tinggi / 100 # dari cm ke meter
imt = berat / (tinggi_m ** 2)
imt = round(imt, 2)
if imt < 18.5:
kategori = "Kurus"
elif 18.5 <= imt < 25:
kategori = "Normal"
elif 25 <= imt < 30:
kategori = "Kelebihan Berat Badan"
else:
kategori = "Obesitas"
label_hasil.config(text=f"IMT Anda: {imt} ({kategori})")
except Exception as e:
messagebox.showerror("Kesalahan", f"Gagal menghitung IMT.\n{str(e)}")
# Tombol hitung ulang
tk.Button(
root_frame,
text="Hitung IMT dari Database",
font=("Arial", 12),
bg="blue",
fg="white",
command=ambil_dan_hitung_imt
).pack(pady=10)
# Tombol kembali
tk.Button(
root_frame,
text="Kembali",
font=("Arial", 12),
bg="gray",
fg="white",
command=lambda: show_menu_profil_kesehatan(root_frame)
).pack(pady=20)
# Hitung otomatis saat tampilan dibuka
ambil_dan_hitung_imt()
๐งช Output Tampilan (Contoh)
Judul: Indeks Massa Tubuh (IMT)
Berat Badan: 65 kg
Tinggi Badan: 170 cm
IMT Anda: 22.49 (Normal)
Jika kamu ingin saya bantu integrasikan ke dalam menu utama atau menambahkan grafik BMI, tinggal beri tahu ya. Siap lanjut ke fitur berikutnya?
Kenapa Nilai BMI dan nilai IMT yang diperoleh adalah bernilai sama, apakah sama rumus penghitungannya
Pertanyaan yang sangat bagus! Jawabannya adalah:
Ya, BMI dan IMT adalah hal yang sama.
๐ Penjelasan:
- IMT adalah singkatan dari Indeks Massa Tubuh (dalam Bahasa Indonesia).
- BMI adalah singkatan dari Body Mass Index (dalam Bahasa Inggris).
Keduanya menggunakan rumus yang sama:
\text{BMI atau IMT} = \frac{\text{Berat Badan (kg)}}{(\text{Tinggi Badan (m)})^2}
๐ Contoh Perhitungan:
Jika:
- Berat badan = 65 kg
- Tinggi badan = 170 cm = 1.70 meter
Maka:
IMT = BMI = \frac{65}{1.7^2} = \frac{65}{2.89} \approx 22.49
✅ Kesimpulan:
- Nilai BMI dan IMT selalu sama karena mereka menggunakan rumus dan satuan yang identik.
- Hanya berbeda penyebutan nama berdasarkan bahasa.
Jadi jika kamu menampilkan nilai IMT atau BMI dalam aplikasi, cukup satu rumus saja yang dipakai.
Kalau kamu ingin menambahkan informasi kategori BMI/IMT, grafik, atau saran berdasarkan hasilnya, aku bisa bantu juga. Siap lanjut ke fitur berikutnya?
Menghitung IMT selain berdasarkan data dari database (data_diri.db), pafa file sub_menu_indeks_massa_tubuh.py buat juga hitungan IMT Secara Manual dengan cara memasukkan input pada kotak entry
Baik! Kita akan lengkapi isi file sub_menu_indeks_massa_tubuh.py agar dapat:
✅ Fitur Utama:
- Menampilkan dan menghitung IMT berdasarkan data dari database (
data_diri.db) - Menampilkan dan menghitung IMT secara manual melalui input kotak entry
- Validasi input untuk memastikan berat & tinggi adalah angka
- Menampilkan kategori IMT (kurus, ideal, gemuk, obesitas)
Berikut kode lengkap sub_menu_indeks_massa_tubuh.py:
import tkinter as tk
import sqlite3
from tkinter import messagebox
DATABASE_PATH = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_diri.db"
def hitung_imt(berat, tinggi_cm):
try:
tinggi_m = tinggi_cm / 100
imt = berat / (tinggi_m ** 2)
return round(imt, 2)
except ZeroDivisionError:
return None
def kategori_imt(imt):
if imt < 18.5:
return "Kurus"
elif 18.5 <= imt < 24.9:
return "Normal / Ideal"
elif 25 <= imt < 29.9:
return "Gemuk"
else:
return "Obesitas"
def show_sub_menu_indeks_massa_tubuh(root_frame):
from menu_profil_kesehatan import show_menu_profil_kesehatan
for widget in root_frame.winfo_children():
widget.destroy()
# Judul
tk.Label(root_frame, text="Indeks Massa Tubuh (IMT)", font=("Arial", 18, "bold"), bg="green", fg="orange", pady=10).pack(pady=20)
# === Hitung dari database ===
def hitung_dari_db():
try:
conn = sqlite3.connect(DATABASE_PATH)
cursor = conn.cursor()
cursor.execute("SELECT berat_badan, tinggi_badan FROM data_diri ORDER BY id DESC LIMIT 1")
result = cursor.fetchone()
conn.close()
if result:
berat, tinggi = result
imt = hitung_imt(berat, tinggi)
kategori = kategori_imt(imt)
hasil_label.config(
text=f"[Dari Database]\nBerat: {berat} kg\nTinggi: {tinggi} cm\nIMT: {imt}\nKategori: {kategori}",
fg="blue"
)
else:
hasil_label.config(text="Data tidak ditemukan di database.", fg="red")
except Exception as e:
messagebox.showerror("Error", str(e))
# === Hitung manual dari input ===
def hitung_manual():
try:
berat = float(entry_berat.get())
tinggi = float(entry_tinggi.get())
if berat <= 0 or tinggi <= 0:
raise ValueError("Berat dan tinggi harus lebih dari 0")
imt = hitung_imt(berat, tinggi)
kategori = kategori_imt(imt)
hasil_label.config(
text=f"[Manual]\nBerat: {berat} kg\nTinggi: {tinggi} cm\nIMT: {imt}\nKategori: {kategori}",
fg="green"
)
except ValueError:
messagebox.showwarning("Input Salah", "Masukkan angka yang valid untuk berat dan tinggi.")
except Exception as e:
messagebox.showerror("Error", str(e))
# Tombol hitung dari database
tk.Button(root_frame, text="Hitung IMT dari Data Diri", font=("Arial", 12), bg="#2196F3", fg="white", command=hitung_dari_db).pack(pady=10)
# Separator
tk.Label(root_frame, text="Atau hitung manual:", font=("Arial", 10, "italic")).pack(pady=(20, 5))
# Form input manual
form_frame = tk.Frame(root_frame)
form_frame.pack()
tk.Label(form_frame, text="Berat (kg):", font=("Arial", 12)).grid(row=0, column=0, sticky="e", padx=5, pady=5)
entry_berat = tk.Entry(form_frame, width=10)
entry_berat.grid(row=0, column=1, padx=5, pady=5)
tk.Label(form_frame, text="Tinggi (cm):", font=("Arial", 12)).grid(row=1, column=0, sticky="e", padx=5, pady=5)
entry_tinggi = tk.Entry(form_frame, width=10)
entry_tinggi.grid(row=1, column=1, padx=5, pady=5)
tk.Button(root_frame, text="Hitung IMT Manual", font=("Arial", 12), bg="#4CAF50", fg="white", command=hitung_manual).pack(pady=10)
# Label hasil
hasil_label = tk.Label(root_frame, text="", font=("Arial", 12), justify="left")
hasil_label.pack(pady=10)
# Tombol kembali
tk.Button(root_frame, text="Kembali", font=("Arial", 12), bg="gray", fg="white", command=lambda: show_menu_profil_kesehatan(root_frame)).pack(pady=30)
✅ Fitur disediakan:
- ✔ Hitung otomatis dari database
data_diri.db - ✔ Hitung manual dari input user
- ✔ Validasi input numerik
- ✔ Menampilkan kategori IMT sesuai standar WHO
- ✔ Tampilan rapi dengan warna berbeda untuk hasil
- ✔ Tombol kembali ke menu sebelumnya
Jika kamu ingin hasil ini disimpan ke database atau ditambahkan grafik status IMT, tinggal beri tahu saja. Siap lanjut ke submenu berikutnya?
Sampai saat ini perubahan, penyempurnaan, dan tambahan file pada applikasi SmartNutriChefAI adalah:
1. menu_profil_kesehatan.py
Kode programnya adalah berikut:
# menu_profil_kesehatan.py
import tkinter as tk
from tkinter import ttk
from sub_menu_data_diri import show_sub_menu_data_diri
from sub_menu_berat_tinggi_badan import show_sub_menu_berat_tinggi_badan
from sub_menu_indeks_massa_tubuh import show_sub_menu_indeks_massa_tubuh
def show_menu_profil_kesehatan(root_frame):
from menu_utama import tampilkan_halaman_utama # Hindari circular import
for widget in root_frame.winfo_children():
widget.destroy()
# Judul
tk.Label(
root_frame,
text="Profil Kesehatan",
font=("Arial", 18, "bold"),
bg="green",
fg="orange",
padx=10,
pady=10
).pack(pady=20)
# Daftar submenu sebagai list tuple: (teks tombol, fungsi yang dipanggil)
submenus = [
("Data Diri", show_sub_menu_data_diri),
("Berat & Tinggi Badan", show_sub_menu_berat_tinggi_badan),
# Tambahkan submenu lain di sini, contoh:
# ("Kalori Harian", show_sub_menu_kalori_harian),
# ("Riwayat BMI", show_sub_menu_riwayat_bmi),
("Indeks Massa Tubuh \n(IMT)", show_sub_menu_indeks_massa_tubuh), # Tambahkan ini
]
# Buat tombol-tombol sub menu
for teks, fungsi in submenus:
tk.Button(
root_frame,
text=teks,
font=("Arial", 12),
bg="light blue",
fg="black",
command=lambda f=fungsi: f(root_frame)
).pack(pady=10)
# Tambahkan separator antar tombol (kecuali terakhir)
ttk.Separator(root_frame, orient='horizontal').pack(fill='x', padx=40, pady=2)
# Tombol kembali
tk.Button(
root_frame,
text="Kembali ke Menu Utama",
font=("Arial", 12),
bg="gray",
fg="white",
command=lambda: tampilkan_halaman_utama(root_frame)
).pack(pady=30)
2. sub_menu_indeks_massa_tubuh.py
Kode programnya adalah berikut:
# sub_menu_indeks_massa_tubuh.py
import tkinter as tk
from tkinter import ttk
from tkinter import messagebox
import sqlite3
import os
def hitung_imt(berat, tinggi_cm):
try:
tinggi_m = tinggi_cm / 100
imt = berat / (tinggi_m ** 2)
return round(imt, 2)
except ZeroDivisionError:
return None
def kategori_imt(imt):
if imt < 18.5:
return "Kurus"
elif 18.5 <= imt < 24.9:
return "Normal / Ideal"
elif 25 <= imt < 29.9:
return "Gemuk"
else:
return "Obesitas"
def show_sub_menu_indeks_massa_tubuh(root_frame):
from menu_profil_kesehatan import show_menu_profil_kesehatan # Hindari circular import
for widget in root_frame.winfo_children():
widget.destroy()
# Judul
label_judul = tk.Label(
root_frame,
text="Indeks Massa Tubuh \n(IMT)",
font=("Arial", 18, "bold"),
bg="green",
fg="orange",
padx=10,
pady=10
)
label_judul.pack(pady=20)
# Label data berat dan tinggi
label_berat = tk.Label(root_frame, text="", font=("Arial", 12))
label_berat.pack(pady=5)
label_tinggi = tk.Label(root_frame, text="", font=("Arial", 12))
label_tinggi.pack(pady=5)
# Label hasil IMT
label_hasil = tk.Label(root_frame, text="", font=("Arial", 12, "bold"), fg="blue")
label_hasil.pack(pady=10)
# Lokasi database
db_path = "/storage/emulated/0/AppJadi/SmartNutriChefAI/Database/data_diri.db"
# Fungsi untuk ambil dan hitung IMT
def ambil_dan_hitung_imt():
if not os.path.exists(db_path):
label_hasil.config(text="Database tidak ditemukan.")
return
try:
conn = sqlite3.connect(db_path)
cursor = conn.cursor()
cursor.execute("SELECT berat, tinggi FROM data_diri ORDER BY id DESC LIMIT 1")
data = cursor.fetchone()
conn.close()
if data is None:
label_hasil.config(text="Data belum tersedia.")
return
berat, tinggi = data
label_berat.config(text=f"Berat Badan: {berat} kg")
label_tinggi.config(text=f"Tinggi Badan: {tinggi} cm")
tinggi_m = tinggi / 100 # dari cm ke meter
imt = berat / (tinggi_m ** 2)
imt = round(imt, 2)
if imt < 18.5:
kategori = "Kurus"
elif 18.5 <= imt < 25:
kategori = "Normal"
elif 25 <= imt < 30:
kategori = "Kelebihan Berat Badan"
else:
kategori = "Obesitas"
label_hasil.config(text=f"IMT Anda: {imt} ({kategori})")
except Exception as e:
messagebox.showerror("Kesalahan", f"Gagal menghitung IMT.\n{str(e)}")
# === Hitung manual dari input ===
def hitung_manual():
try:
berat = float(entry_berat.get())
tinggi = float(entry_tinggi.get())
if berat <= 0 or tinggi <= 0:
raise ValueError("Berat dan tinggi harus lebih dari 0")
imt = hitung_imt(berat, tinggi)
kategori = kategori_imt(imt)
hasil_label.config(
text=f"[Manual]\nBerat: {berat} kg\nTinggi: {tinggi} cm\nIMT: {imt}\nKategori: {kategori}",
fg="green"
)
except ValueError:
messagebox.showwarning("Input Salah", "Masukkan angka yang valid untuk berat dan tinggi.")
except Exception as e:
messagebox.showerror("Error", str(e))
# Tambahkan separator antar tombol (kecuali terakhir)
ttk.Separator(root_frame, orient='horizontal').pack(fill='x', padx=40, pady=2)
# Separator
tk.Label(root_frame, text="Atau hitung IMT secara manual:", font=("Arial", 10, "italic")).pack(pady=(20, 5))
# Form input manual
form_frame = tk.Frame(root_frame)
form_frame.pack()
tk.Label(form_frame, text="Berat (kg):", font=("Arial", 12)).grid(row=0, column=0, sticky="e", padx=5, pady=5)
entry_berat = tk.Entry(form_frame, width=10)
entry_berat.grid(row=0, column=1, padx=5, pady=5)
tk.Label(form_frame, text="Tinggi (cm):", font=("Arial", 12)).grid(row=1, column=0, sticky="e", padx=5, pady=5)
entry_tinggi = tk.Entry(form_frame, width=10)
entry_tinggi.grid(row=1, column=1, padx=5, pady=5)
tk.Button(root_frame, text="Hitung IMT Manual", font=("Arial", 12), bg="#4CAF50", fg="white", command=hitung_manual).pack(pady=10)
# Label hasil
hasil_label = tk.Label(root_frame, text="", font=("Arial", 12), justify="left")
hasil_label.pack(pady=10)
# Tombol kembali
tk.Button(
root_frame,
text="Kembali",
font=("Arial", 12),
bg="gray",
fg="white",
command=lambda: show_menu_profil_kesehatan(root_frame)
).pack(pady=20)
# Hitung otomatis saat tampilan dibuka
ambil_dan_hitung_imt()
Bersambung Ke: Konten Sub Menu "Riwayat Kesehatan"
Comments
Post a Comment