BRA-FIT / app.py
ramagururadhakrishnan's picture
Fine tuning features
18b0298 verified
import streamlit as st
import pandas as pd
import json
import datetime
import os
import plotly.express as px
from fpdf import FPDF
st.set_page_config(page_title="BRA Research Academy - Bra Fit Survey", layout="centered")
st.title("πŸ‘™ BRA-FIT Survey (BRA Research Academy)")
tab1, tab2 = st.tabs(["πŸ“ Survey Form", "πŸ“Š Visualizations"])
# Create folder to store surveys
if not os.path.exists("survey_data"):
os.makedirs("survey_data")
# File to store and track BRAID counter
braid_counter_file = "braid_counter.txt"
if not os.path.exists(braid_counter_file):
with open(braid_counter_file, "w") as f:
f.write("1000") # Initial BRAID number
# Function to get the next BRAID in serial order
def get_next_braid():
with open(braid_counter_file, "r") as f:
current_braid = int(f.read().strip())
next_braid = current_braid + 1
with open(braid_counter_file, "w") as f:
f.write(str(next_braid))
return f"BRAID{current_braid}"
# PDF class
class PDF(FPDF):
def header(self):
self.set_font('Arial', 'B', 14)
self.cell(0, 10, 'BRA-FIT Survey Report', ln=True, align='C')
self.ln(10)
def chapter_title(self, title):
self.set_font('Arial', 'B', 12)
self.cell(0, 10, title, ln=True)
self.ln(4)
def chapter_body(self, body):
self.set_font('Arial', '', 12)
self.multi_cell(0, 10, body)
self.ln()
def generate_pdf(data, braid):
if isinstance(data, str):
data = json.loads(data) # Convert string back to dict if needed
pdf = PDF()
pdf.add_page()
pdf.chapter_title(f"Braid Number: {braid}")
for section, details in data.items():
pdf.chapter_title(section)
body = "\n".join([f"{k}: {v}" for k, v in details.items()])
pdf.chapter_body(body)
return pdf.output(dest='S').encode('latin-1')
with tab1:
st.header("Section A: Demographics & Background")
age = st.number_input("Age", min_value=20, max_value=60)
occupation = st.text_input("Occupation")
city_state = st.text_input("City & State")
body_type = st.selectbox("Body Type", ["Petite", "Tall", "Plus-size", "Average"])
activity_level = st.selectbox("Activity Level", ["Sedentary", "Active", "Highly Active"])
professional_fitting = st.radio("Have you ever had a professional bra fitting?", ["Yes", "No"])
st.header("Section B: Breast & Body Details")
breast_size = st.text_input("Approximate Breast Size (if known)")
breast_shape = st.selectbox(
"Breast Shape",
["Round", "Bell-shaped", "East-West", "Side set", "Teardrop", "Asymmetrical", "Athletic", "Relaxed"]
)
asymmetry = st.radio("Any Asymmetry?", ["No", "Yes - Left Larger", "Yes - Right Larger"])
underbust_cm = st.number_input("Underbust Measurement (cm)")
bust_cm = st.number_input("Bust Measurement (cm)")
rib_cage_shape = st.text_input("Rib Cage Shape (broad, narrow, protruding, flat)")
st.header("Section C: Bra Usage & Habits")
current_bra_size = st.text_input("Current Bra Size")
preferred_brands = st.text_input("Preferred Brands")
preferred_styles = st.multiselect(
"Preferred Bra Styles",
["T-shirt", "Balconette", "Plunge", "Bralette", "Sports", "Full coverage", "Others"]
)
fit_issues = st.multiselect(
"Common Fit Issues",
["Tight band", "Spillage", "Straps dig in", "Underwire pokes", "Gaping cups", "Center gore not tacking"]
)
replace_frequency = st.selectbox(
"How often do you replace your bras?",
["Every 6 months", "Every year", "Every 2+ years", "Rarely"]
)
dispose_method = st.text_input("How do you usually dispose of old bras?")
open_to_try = st.radio("Open to trying new bra styles/sizes?", ["Yes", "No"])
willing_for_trial = st.radio("Willing to participate in bra trial & feedback?", ["Yes", "No"])
# Submit button
if st.button("Submit and Generate Report"):
# Check if any required field is empty
form_data = {
"Section A: Demographics & Background": {
"Age": age,
"Occupation": occupation,
"City & State": city_state,
"Body Type": body_type,
"Activity Level": activity_level,
"Professional Bra Fitting": professional_fitting
},
"Section B: Breast & Body Details": {
"Approximate Breast Size": breast_size,
"Breast Shape": breast_shape,
"Asymmetry": asymmetry,
"Underbust Measurement (cm)": underbust_cm,
"Bust Measurement (cm)": bust_cm,
"Rib Cage Shape": rib_cage_shape
},
"Section C: Bra Usage & Habits": {
"Current Bra Size": current_bra_size,
"Preferred Brands": preferred_brands,
"Preferred Styles": preferred_styles,
"Common Fit Issues": fit_issues,
"Replace Frequency": replace_frequency,
"Dispose Method": dispose_method,
"Open to Trying New Styles/Sizes": open_to_try,
"Willing to Participate in Trials": willing_for_trial
}
}
# Validate if all fields are filled
missing_fields = []
for section, details in form_data.items():
for field, value in details.items():
if not value:
missing_fields.append(f"{field} in {section}")
if missing_fields:
st.error(f"Missing required fields in: {', '.join(missing_fields)}. Please fill them out.")
else:
st.success("Form submitted successfully!")
# Get next BRAID in serial order
unique_id = get_next_braid()
timestamp = datetime.datetime.now().strftime("%Y%m%d%H%M%S")
# Convert data for saving
json_data = json.dumps(form_data, indent=4)
flat_data = {}
for section, items in form_data.items():
for k, v in items.items():
if isinstance(v, list):
v = ", ".join(v)
flat_data[k] = v
df = pd.DataFrame([flat_data])
# Save JSON to memory
json_file = json.dumps(form_data, indent=4)
# Save PDF to memory
pdf_file = generate_pdf(form_data, unique_id)
# Provide download buttons for the reports
st.download_button(
label="πŸ“„ Download Report as JSON",
data=json_file,
file_name=f"{unique_id}_bra_fit_survey.json",
mime="application/json"
)
st.download_button(
label="πŸ“„ Download Report as PDF",
data=pdf_file,
file_name=f"{unique_id}_bra_fit_survey.pdf",
mime="application/pdf"
)
st.download_button(
label="πŸ“„ Download Report as CSV",
data=df.to_csv(index=False).encode('utf-8'),
file_name=f"{unique_id}_bra_fit_survey.csv",
mime="text/csv"
)
with tab2:
st.header("πŸ“Š Visualizations from Survey Data")
# Load all JSON files
all_data = []
for file in os.listdir("survey_data"):
if file.endswith(".json"):
with open(os.path.join("survey_data", file)) as f:
data = json.load(f)
flat_record = {}
for section, items in data.items():
for k, v in items.items():
if isinstance(v, list):
v = ", ".join(v)
flat_record[k] = v
all_data.append(flat_record)
if all_data:
df = pd.DataFrame(all_data)
st.subheader("Age Distribution")
st.bar_chart(df['Age'])
st.subheader("Preferred Styles")
if 'Preferred Styles' in df.columns:
preferred_styles_series = df['Preferred Styles'].str.split(", ").explode()
style_counts = preferred_styles_series.value_counts().reset_index()
style_counts.columns = ['Style', 'Count']
fig = px.pie(style_counts, names='Style', values='Count', title='Preferred Bra Styles')
st.plotly_chart(fig)
st.subheader("Fit Issues")
if 'Common Fit Issues' in df.columns:
fit_issues_series = df['Common Fit Issues'].str.split(", ").explode()
issues_counts = fit_issues_series.value_counts().reset_index()
issues_counts.columns = ['Issue', 'Count']
fig2 = px.bar(issues_counts, x='Issue', y='Count', title='Common Fit Issues')
st.plotly_chart(fig2)
st.subheader("Activity Level Distribution")
if 'Activity Level' in df.columns:
activity_counts = df['Activity Level'].value_counts().reset_index()
activity_counts.columns = ['Activity Level', 'Count']
fig3 = px.pie(activity_counts, names='Activity Level', values='Count', title='Activity Levels')
st.plotly_chart(fig3)
else:
st.info("No survey data found. Please submit the survey form first.")