| | import streamlit as st |
| | from transformers import AutoTokenizer, AutoModelForSeq2SeqLM |
| | import torch |
| |
|
| | |
| | st.set_page_config(page_title="FitPlan AI", page_icon="💪", layout="centered") |
| |
|
| | def load_model(): |
| | tokenizer = AutoTokenizer.from_pretrained("google/flan-t5-base") |
| | model = AutoModelForSeq2SeqLM.from_pretrained("google/flan-t5-base") |
| | return tokenizer, model |
| | |
| | tokenizer, model = load_model() |
| |
|
| | generator = load_model() |
| | |
| | st.markdown(""" |
| | <style> |
| | /* Full Page Background */ |
| | [data-testid="stAppViewContainer"] { |
| | background: linear-gradient(rgba(0, 0, 0, 0.75), rgba(0, 0, 0, 0.75)), |
| | url("https://images.unsplash.com/photo-1517836357463-d25dfeac3438?q=80&w=2070&auto=format&fit=crop"); |
| | background-size: cover; |
| | background-position: center; |
| | background-attachment: fixed; |
| | } |
| | /* Hide the "Press Enter to submit form" hint globally */ |
| | [data-testid="InputInstructions"] { |
| | display: none !important; |
| | } |
| | /* Form Container Polish */ |
| | div[data-testid="stForm"] { |
| | background-color: rgba(255, 255, 255, 0.98) !important; |
| | padding: 3rem !important; |
| | border-radius: 20px !important; |
| | border: none !important; |
| | box-shadow: 0 15px 35px rgba(0,0,0,0.5); |
| | } |
| | /* --- FONT SIZE UPDATES --- */ |
| | /* Main Title (FitPlan AI) */ |
| | .main-title { |
| | color: #FFFFFF !important; |
| | font-size: 60px !important; |
| | font-weight: 850 !important; |
| | text-align: center; |
| | margin-bottom: 0px; |
| | text-shadow: 3px 3px 6px rgba(0,0,0,0.9); |
| | font-family: 'Helvetica Neue', sans-serif; |
| | } |
| | /* Subtitle (Your personalized gym companion) */ |
| | .sub-title { |
| | color: #E0E0E0 !important; |
| | font-size: 24px !important; |
| | text-align: center; |
| | margin-top: -10px; |
| | margin-bottom: 40px; |
| | font-style: italic; |
| | text-shadow: 1px 1px 3px rgba(0,0,0,0.8); |
| | } |
| | /* Form Section Headers (Orange) */ |
| | .form-header { |
| | color: #f97316 !important; |
| | font-size: 22px !important; |
| | font-weight: bold !important; |
| | text-transform: uppercase; |
| | letter-spacing: 1px; |
| | } |
| | /* Labels for inputs */ |
| | label p { |
| | font-size: 18px !important; |
| | color: #1e293b !important; |
| | font-weight: 600 !important; |
| | } |
| | /* Button Styling */ |
| | .stButton > button { |
| | width: 100%; |
| | background: linear-gradient(90deg, #f97316, #ea580c) !important; |
| | color: white !important; |
| | font-size: 20px !important; |
| | font-weight: bold !important; |
| | height: 3.5rem !important; |
| | border-radius: 12px !important; |
| | border: none !important; |
| | margin-top: 20px; |
| | } |
| | </style> |
| | """, unsafe_allow_html=True) |
| |
|
| | |
| | |
| | |
| | st.markdown('<p class="main-title">💪 FitPlan AI</p>', unsafe_allow_html=True) |
| | st.markdown('<p class="sub-title">Your personalized gym companion</p>', unsafe_allow_html=True) |
| |
|
| | |
| | |
| | |
| | with st.form("fitness_form", clear_on_submit=False): |
| | st.markdown('<p class="form-header">🧍♂️ 1. PERSONAL INFORMATION</p>', unsafe_allow_html=True) |
| | |
| | name = st.text_input("Full Name *", placeholder="Enter your full name") |
| |
|
| | col1, col2 = st.columns(2) |
| | with col1: |
| | height = st.number_input("Height (cm) *", min_value=0.0, step=1.0, value=0.0) |
| | with col2: |
| | weight = st.number_input("Weight (kg) *", min_value=0.0, step=0.1, value=0.0) |
| |
|
| | st.markdown("<br>", unsafe_allow_html=True) |
| | st.markdown('<p class="form-header">🏋️ 2. FITNESS DETAILS</p>', unsafe_allow_html=True) |
| | |
| | goal = st.selectbox("Fitness Goal", ["Build Muscle", "Weight Loss", "Strength Gain", "Abs Building", "Flexible"]) |
| | |
| | equipment = st.multiselect("Available Equipment", |
| | ["Dumbbells", "Resistance Band", "Yoga Mat", "Kettlebell", "Pull-up Bar", "No Equipment"], |
| | default=["No Equipment"]) |
| | |
| | level = st.radio("Fitness Level", ["Beginner", "Intermediate", "Advanced"], horizontal=True) |
| |
|
| | |
| | if st.button(" Submit Profile"): |
| | |
| | if not name: |
| | st.error("Please enter your name.") |
| | |
| | elif height <= 0 or weight <= 0: |
| | st.error("Please enter valid height and weight.") |
| | |
| | elif not equipment: |
| | st.error("Please select at least one equipment option.") |
| | |
| | else: |
| | st.success(" Profile Submitted Successfully!") |
| | |
| | bmi_status = bmi_category(bmi) |
| | equipment_list = ", ".join(equipment) |
| | |
| | prompt = f""" |
| | You are a certified professional fitness trainer. |
| | |
| | Create a detailed 5-day workout plan. |
| | |
| | User Information: |
| | - Gender: {gender} |
| | - BMI: {bmi:.2f} ({bmi_status}) |
| | - Goal: {goal} |
| | - Fitness Level: {fitness_level} |
| | - Equipment Available: {equipment_list} |
| | |
| | Start directly with: |
| | |
| | Day 1: |
| | """ |
| | |
| | with st.spinner("Generating your AI workout plan..."): |
| | |
| | inputs = tokenizer(prompt, return_tensors="pt", truncation=True) |
| | |
| | outputs = model.generate( |
| | **inputs, |
| | max_new_tokens=900, |
| | temperature=0.7, |
| | do_sample=True |
| | ) |
| | |
| | result = tokenizer.decode(outputs[0], skip_special_tokens=True).strip() |
| | |
| | st.subheader(" Your Personalized Workout Plan") |
| | st.write(result) |