신체 정보를 넣을 시 운동 및 식단을 알려주는 챗봇

배경 및 목적

AI 찐뉴비로 어떤걸 만들어볼까 생각을 하다 그냥 물어보기로 했습니다.

검정색 배경에 한국어 텍스트

나만의 피트니스 선생님 있으면 좋겠다는 생각과 함께 만들어보기로 했습니다.

실행 과정

일단 질문은 위 "개인화된 피트니스 추천 시스템" 복사하고 VS CODE에서 파이썬 코드를 사용하여 스트리밋을 활용해서 만들고 싶어 나는 초보니까 상세하게 알려줘" 라고 말하니

import streamlit as st

# 사용자 데이터 입력 폼
st.title("개인화 피트니스 추천 시스템")

# 사용자로부터 입력받는 데이터
height = st.number_input("키 (cm)", min_value=100, max_value=250, value=170)
weight = st.number_input("체중 (kg)", min_value=30, max_value=200, value=70)
goal_weight = st.number_input("목표 체중 (kg)", min_value=30, max_value=200, value=65)
age = st.number_input("나이", min_value=10, max_value=100, value=25)
gender = st.selectbox("성별", ["남성", "여성"])
activity_level = st.selectbox("활동 수준", ["저활동", "중간활동", "고활동"])

# 입력된 데이터를 출력해주는 부분
st.write("입력된 데이터:")
st.write(f"키: {height} cm, 체중: {weight} kg, 목표 체중: {goal_weight} kg")
st.write(f"나이: {age}, 성별: {gender}, 활동 수준: {activity_level}")

# 운동 루틴 추천
st.write("추천 운동:")
if activity_level == "저활동":
    st.write("가벼운 유산소 운동 (예: 걷기, 자전거 타기)")
elif activity_level == "중간활동":
    st.write("중간 강도의 유산소 운동 (예: 달리기, 수영)")
else:
    st.write("고강도 운동 (예: HIIT, 웨이트 트레이닝)")

# 식단 추천
st.write("추천 식단:")
if goal_weight < weight:
    st.write("저칼로리 식단을 추천합니다.")
else:
    st.write("단백질 위주의 근육 강화 식단을 추천합니다.")

import matplotlib.pyplot as plt

# 체중 변화 추적을 시각화
st.write("체중 변화 추적 그래프:")
weight_history = [weight, goal_weight - 2, goal_weight - 4]  # 예시 데이터로 대체 가능
plt.plot(weight_history)
plt.title('체중 변화 추적')
plt.xlabel('시간(주)')
plt.ylabel('체중(kg)')
st.pyplot(plt)

코드를 주더라구요. 붙여서 실행해보니

검은 화면에 한국어 스크린샷

허접하지만 첫 스트리밋 화면이 실행됐습니다..!

이제 여기다가 고민한 건 OPENAI API를 연결해서 저 내용을 바탕으로

식단과 운동을 알려주는 챗봇을 만들어보려고 했습니다.

import streamlit as st
import openai

# OpenAI API 설정
openai.api_key = "API키"  # 발급받은 API 키를 여기에 넣으세요

# 사용자 데이터 입력 폼
st.title("개인화 피트니스 추천 시스템")

# 사용자로부터 입력받는 데이터
height = st.number_input("키 (cm)", min_value=100, max_value=250, value=170)
weight = st.number_input("체중 (kg)", min_value=30, max_value=200, value=70)
goal_weight = st.number_input("목표 체중 (kg)", min_value=30, max_value=200, value=65)
age = st.number_input("나이", min_value=10, max_value=100, value=25)
gender = st.selectbox("성별", ["남성", "여성"])
activity_level = st.selectbox("활동 수준", ["저활동", "중간활동", "고활동"])

# 입력된 데이터를 출력해주는 부분
st.write("입력된 데이터:")
st.write(f"키: {height} cm, 체중: {weight} kg, 목표 체중: {goal_weight} kg")
st.write(f"나이: {age}, 성별: {gender}, 활동 수준: {activity_level}")

# OpenAI를 활용한 운동 및 식단 추천 챗봇
def get_fitness_recommendations():
    user_info = (
        f"User Info: Height: {height} cm, Weight: {weight} kg, Goal Weight: {goal_weight} kg, "
        f"Age: {age}, Gender: {gender}, Activity Level: {activity_level}."
    )

    prompt = (
        f"{user_info}\n"
        "Based on this information, recommend a personalized workout plan and diet plan."
    )

    # OpenAI API 호출
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",  # 최신 GPT-3.5 모델 사용
        messages=[
            {"role": "system", "content": "You are a fitness expert."},
            {"role": "user", "content": prompt}
        ],
        max_tokens=300,
        temperature=0.7
    )

    return response['choices'][0]['message']['content']

# 추천 버튼 추가
if st.button("운동 및 식단 추천 받기"):
    recommendations = get_fitness_recommendations()
    st.write("추천 결과:")
    st.write(recommendations)

오류 몇 번과 함께 일단 나오게는 만들었습니다.

검정색 배경을 가진 사람을 위한 운동 계획

영어로요...

한글로 나오게 부탁하고, 글자를 어떻게 안 짤리게 할까 고민하니 AI가 나눠서 적을 수 있게 추천해주더라구요. 운동 방법 / 식단 조절 이런식으로요. 그럼에 글자는 계속 짤려서 그냥 표 형태로 나오게끔 하는게 제일 깔끔하겠다 생각해서 코드를 작성했고

import streamlit as st
import openai
import pandas as pd

# OpenAI API 설정
openai.api_key = "API키"  # 발급받은 API 키를 여기에 넣으세요

# 사용자 데이터 입력 폼
st.title("개인화 피트니스 추천 시스템")

# 사용자로부터 입력받는 데이터
height = st.number_input("키 (cm)", min_value=100, max_value=250, value=170)
weight = st.number_input("체중 (kg)", min_value=30, max_value=200, value=70)
goal_weight = st.number_input("목표 체중 (kg)", min_value=30, max_value=200, value=65)
age = st.number_input("나이", min_value=10, max_value=100, value=25)
gender = st.selectbox("성별", ["남성", "여성"])
activity_level = st.selectbox("활동 수준", ["저활동", "중간활동", "고활동"])

# 입력된 데이터를 출력해주는 부분
st.write("입력된 데이터:")
st.write(f"키: {height} cm, 체중: {weight} kg, 목표 체중: {goal_weight} kg")
st.write(f"나이: {age}, 성별: {gender}, 활동 수준: {activity_level}")

# OpenAI를 활용한 운동 및 식단 추천 챗봇
def get_recommendations(type):
    user_info = (
        f"User Info: Height: {height} cm, Weight: {weight} kg, Goal Weight: {goal_weight} kg, "
        f"Age: {age}, Gender: {gender}, Activity Level: {activity_level}."
    )
    
    if type == "운동":
        prompt = (
            f"{user_info}\n"
            "위 정보를 바탕으로 7일치 운동 계획과 각 운동당 칼로리 소모량을 표 형식으로 추천해 주세요."
        )
    elif type == "식단":
        prompt = (
            f"{user_info}\n"
            "위 정보를 바탕으로 7일치 아침, 점심, 저녁 식단을 표 형식으로 추천해 주세요."
        )

    # OpenAI API 호출
    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",  # 최신 GPT-3.5 모델 사용
        messages=[
            {"role": "system", "content": "You are a fitness and nutrition expert."},
            {"role": "user", "content": prompt}
        ],
        max_tokens=1000,
        temperature=0.7
    )

    return response['choices'][0]['message']['content']

# 운동 계획 추천
if st.button("운동 계획 추천 받기"):
    workout_plan = get_recommendations("운동")
    st.write("운동 계획:")
    
    # 예시 데이터를 사용하여 표 형식으로 표시
    workout_data = {
        "요일": ["월", "화", "수", "목", "금", "토", "일"],
        "운동": ["달리기 30분", "자전거 45분", "수영 30분", "휴식", "웨이트 60분", "달리기 45분", "휴식"],
        "칼로리 소모": [300, 400, 350, 0, 500, 450, 0]
    }
    
    df_workout = pd.DataFrame(workout_data)
    st.table(df_workout)

# 식단 계획 추천
if st.button("식단 계획 추천 받기"):
    diet_plan = get_recommendations("식단")
    st.write("식단 계획:")

    # 예시 데이터를 사용하여 표 형식으로 표시
    diet_data = {
        "요일": ["월", "화", "수", "목", "금", "토", "일"],
        "아침": ["계란 + 오트밀", "그릭 요거트", "과일 + 견과류", "계란 + 토스트", "오트밀", "그릭 요거트", "계란 + 채소"],
        "점심": ["닭가슴살 샐러드", "연어 샐러드", "현미밥 + 야채", "닭가슴살 샐러드", "연어 샐러드", "현미밥 + 야채", "닭가슴살 샐러드"],
        "저녁": ["구운 채소", "찐 생선", "닭가슴살", "구운 채소", "찐 생선", "닭가슴살", "구운 채소"]
    }
    
    df_diet = pd.DataFrame(diet_data)
    st.table(df_diet)
검은 화면에 한국 이름 목록

이런 결과값을 얻었습니다!

그런데요.. 위에 몸무게와 키를 변경해도 운동계획과 식단은 안바뀌더라구요

코드에 예시로 적은 내용만 나오는 것 같아서 이를 해결하기 위해 다시 또 질문했습니다.

질문은 "나는 표에 대한 내용을 AI가 위에 "입력된 데이터:"를 토대로 분석해서 이에 맞는 운동법과 식단을 얘기해주길 원하는데 지금은 예시에 있는 내용만 알려주고 있어 이를 해결하기 위해서는 어떻게 해야해?" 이렇게 적었습니다. 이에 맞는 코드를 알려주고 넣어서 실행하니

  1. 키 : 180cm, 체중 95kg, 저활동, 남, 나이 31 / 목표 체중 80kg

한국어 메뉴 스크린샷
검은 배경에 한국 이름 목록

  1. 키 : 185cm, 체중 75kg, 저활동, 남, 나이 31 / 목표 체중 : 87kg

한국판 게임 스크린샷
검은 화면에 한국 이름 목록

정확하게 이에 맞는 운동인지는 아직 모르겠으나, 키와 몸무게와 목표체중을 넣었을 때 각각 다르게 알려주고 운동 및 식단을 알려주는 챗봇을 만들었습니다.

이제 디자인적인 부분들이 너무 허접한거 같아서 피트니스 센터 느낌으로 만들어달랬더니

한국어 문자가 포함된 한국어 앱의 스크린샷

충격적으로 만들어줬습니다.. 아직 AI의 마음을 모르겠습니다

뭔가 그.. 이건 아니다 싶은데 어디서부터 어떤 질문을 하면 좋을지에 대해 잘 모르겠더라구요

프롬프트의 중요성을 다시 한번 더 생각하는 시간이었습니다..

디자인적으로 요청하다보니 갑자기 잘되던 AI 답변이 망가지고 이거 고치니 저거 안되고

하다보니 당황도 많이 하고 추가보다 일단 실행을 하는데 중점을 둬야겠다고 생각했습니다.

결과 및 인사이트

한국어 텍스트가 포함된 웹페이지의 스크린샷
한국사이트 스크린샷

일단 키와 몸무게 및 나이, 성별 등을 넣고 맞춤체형을 넣으면

그에 맞춰 AI가 판단하여 식단 및 운동을 알려주는 챗봇을 만들어봤습니다.

많이 허접하고 부족한 부분들이 어쩔 수 없이 생기는 것 같다는 생각을 하게 됐습니다.

하면서 코딩을 모르더라도 만들어지는게 신기했지만 어느정도 알아야 잘 만들 수 있겠구나와 어떻게 질문을 해야 내가 머릿속에 생각한 부분이 나올까에 대해 고민하는 시간이었습니다.

혹시나 필요하신 분 있을 수 있으니 코드 공유하겠습니다

좀 더 발전해서 돌아오도록 하겠습니다 감사합니다:)

(코드 공유)

import streamlit as st
import openai

# OpenAI API 설정
openai.api_key = ""  # 발급받은 API 키를 여기에 넣으세요

# 페이지 기본 설정
st.set_page_config(page_title="맞춤형 피트니스 추천 시스템", layout="wide", initial_sidebar_state="expanded")

# 사용자 정의 CSS 추가 (다크 모드 스타일 적용)
st.markdown("""
    <style>
    .main {
        background-color: #1e1e1e;  /* 전체 배경 어둡게 */
        color: #ffffff;  /* 기본 텍스트를 밝게 */
        font-family: 'Helvetica Neue', sans-serif;
    }
    h1, h2 {
        color: #ffcc00;  /* 헤더 텍스트를 밝은 노란색으로 */
        font-weight: bold;
    }
    .block-container {
        padding: 1rem 2rem;
    }
    .stButton button {
        background-color: #ff6347;  /* 버튼을 밝은 색으로 */
        color: white;
        border-radius: 12px;
        padding: 12px 24px;
        font-size: 1.3rem;
        font-weight: bold;
        transition: background-color 0.3s ease;
        box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2);
    }
    .stButton button:hover {
        background-color: #ff4500;
        color: white;
        transform: scale(1.05);
    }
    .stTextInput>div>input {
        background-color: #333333;  /* 입력 상자 어둡게 */
        color: white;
        border-radius: 10px;
        padding: 10px;
        font-size: 1.1rem;
    }
    .stSelectbox>div>div>div>button {
        background-color: #333333;  /* 셀렉트 박스 어둡게 */
        color: white;
        border-radius: 10px;
        padding: 10px;
        font-size: 1.1rem;
    }
    .stTable {
        margin-top: 2rem;
    }
    .stMarkdown p {
        color: white !important;  /* 마크다운 텍스트를 흰색으로 */
        font-size: 1.2rem;
    }
    </style>
""", unsafe_allow_html=True)

# OpenAI API를 호출하는 함수
def get_recommendations(type, user_info):
    if type == "운동":
        prompt = f"{user_info}\n위 정보를 바탕으로 7일 운동 계획을 세우고 칼로리 소모량을 포함하여 추천해 주세요."
    elif type == "식단":
        prompt = f"{user_info}\n위 정보를 바탕으로 7일치 식단 계획을 아침, 점심, 저녁으로 나눠서 추천해 주세요."

    response = openai.ChatCompletion.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "system", "content": "You are a fitness and nutrition expert."},
                  {"role": "user", "content": prompt}],
        max_tokens=1000,
        temperature=0.7
    )

    return response.choices[0].message['content']

# 운동 및 식단 계획을 텍스트 형식으로 깔끔하게 출력하는 함수
def format_plan_to_text(plan_data):
    formatted_text = ""
    for day in plan_data:
        formatted_text += f"**{day['날짜']}**\n"
        formatted_text += f"- 운동 내용: {day['운동 내용']}\n"
        formatted_text += f"- 운동 시간: {day['운동 시간']}\n"
        formatted_text += f"- 칼로리 소모량: {day['칼로리 소모량']}\n\n"
    return formatted_text

# 타이틀 섹션
st.title("💪 맞춤형 피트니스 추천 시스템")

# 사용자 입력 받기
col1, col2 = st.columns(2)

with col1:
    st.header("📋 운동 계획 추천")
    height = st.number_input("키 (cm)", min_value=100, max_value=250, value=170)
    weight = st.number_input("체중 (kg)", min_value=30, max_value=200, value=70)
    goal_weight = st.number_input("목표 체중 (kg)", min_value=30, max_value=200, value=65)
    age = st.number_input("나이", min_value=10, max_value=100, value=25)
    gender = st.selectbox("성별", ["남성", "여성"])
    activity_level = st.selectbox("활동 수준", ["저활동", "중간활동", "고활동"])

    user_info = (
        f"사용자 정보: 키 {height}cm, 체중 {weight}kg, 목표 체중 {goal_weight}kg, 나이 {age}, "
        f"성별 {gender}, 활동 수준 {activity_level}."
    )

    # 운동 계획 추천 버튼
    if st.button("🏃‍♂️ 운동 계획 추천 받기"):
        workout_plan = get_recommendations("운동", user_info)
        st.markdown(f"**AI 추천 운동 계획**\n\n{workout_plan}")

with col2:
    st.header("🍽️ 식단 계획 추천")
    if st.button("🍲 식단 계획 추천 받기"):
        diet_plan = get_recommendations("식단", user_info)
        st.markdown(f"**AI 추천 식단 계획**\n\n{diet_plan}")

5
1개의 답글

뉴스레터 무료 구독

👉 이 게시글도 읽어보세요