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.py
import tkinter as tk
from tkinter import messagebox
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)
# Frame input
form_frame = tk.Frame(root_frame)
form_frame.pack(pady=10)
# Berat badan
tk.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 badan
tk.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 hasil
label_hasil = tk.Label(root_frame, text="", font=("Arial", 12, "bold"), fg="blue")
label_hasil.pack(pady=10)
# Fungsi hitung IMT
def hitung_imt():
try:
berat = float(entry_berat.get())
tinggi_cm = float(entry_tinggi.get())
tinggi_m = tinggi_cm / 100
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 ValueError:
messagebox.showerror("Input Tidak Valid", "Masukkan angka yang benar untuk berat dan tinggi badan.")
# Tombol hitung
tk.Button(
root_frame,
text="Hitung IMT",
font=("Arial", 12),
bg="blue",
fg="white",
command=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)

๐Ÿ”ง Langkah Selanjutnya:

  1. Tambahkan tombol baru di menu_profil_kesehatan.py:
from sub_menu_indeks_massa_tubuh import show_sub_menu_indeks_massa_tubuh
submenu_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:

  1. Menampilkan dan menghitung IMT berdasarkan data dari database (data_diri.db)
  2. Menampilkan dan menghitung IMT secara manual melalui input kotak entry
  3. Validasi input untuk memastikan berat & tinggi adalah angka
  4. 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

Popular posts from this blog

Isi Menu "Setting"

Isi Menu "Riwayat Aktivitas" (Bagian 2)