JUNGU's picture
Update app.py
7fc494d verified
import streamlit as st
import openai
import json
from annotated_text import annotated_text
import os
import pandas as pd
import achivenment_standards as data
# OpenAI API μ„€μ • (ν™˜κ²½ λ³€μˆ˜μ—μ„œ μ½μ–΄μ˜΄)
openai.api_key = os.getenv("OPENAI_API_KEY")
# gptμ΄μš©ν•΄μ„œ μΆ”λ‘ ν•¨μˆ˜ λ§Œλ“€κΈ°
def generate_annotated_text(text):
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": "μ„±μ·¨κΈ°μ€€ 기반 ν•™μƒμ˜ νŠΉμ„± 및 ν™œλ™ 평가 생성\n성취기쀀을 μž…λ ₯ν•˜μ‹œλ©΄, ν•΄λ‹Ή 성취기쀀에 κΈ°λ°˜ν•œ ν•™μƒμ˜ νŠΉμ„± 및 ν™œλ™μ— λŒ€ν•œ 평가λ₯Ό annotated_text ν˜•μ‹μœΌλ‘œ μ œκ³΅ν•©λ‹ˆλ‹€. 성취기쀀을 보며 ν•™μƒμ˜ νŠΉμ • ν™œλ™, μ„±μ·¨ μˆ˜μ€€, κ΅μ‚¬μ˜ 총평, 그리고 ν•™μƒμ˜ μ—­λŸ‰μ„ κ³ λ €ν•˜μ—¬ μ²΄κ³„μ μœΌλ‘œ κ΅¬μ„±λœ 좜λ ₯을 μ œκ³΅ν•©λ‹ˆλ‹€. μ£Όμ–΄λŠ” λ°˜λ“œμ‹œ μƒλž΅ν•©λ‹ˆλ‹€. \n\n예제:\nμž…λ ₯: ```μ„±μ·¨κΈ°μ€€: [6κ΅­01-07]μƒλŒ€κ°€ μ²˜ν•œ 상황을 μ΄ν•΄ν•˜κ³  κ³΅κ°ν•˜λ©° λ“£λŠ” νƒœλ„λ₯Ό μ§€λ‹Œλ‹€, [6κ΅­01-02] μ˜κ²¬μ„ μ œμ‹œν•˜κ³  ν•¨κ»˜ μ‘°μ •ν•˜λ©° ν† μ˜ν•œλ‹€.```\n좜λ ₯: ```annotated_text(\n (\"ν‰μ†Œ μžμ‹ μ˜ 생각을 일λͺ©μš”μ—°ν•˜κ²Œ μ •λ¦¬ν•˜λŠ” μŠ΅κ΄€μ΄ 있음.\", \"μ—­λŸ‰\", \"rgba(255, 0, 0, 0.3)\"),\n (\"μ‚¬νšŒ ν˜„μ•ˆμ— κ΄€ν•œ μ£Όμž₯ν•˜λŠ” κΈ€μ“°κΈ°λ₯Ό μž˜ν•¨.\", \"μ„±μ·¨μˆ˜μ€€\", \"rgba(0, 0, 255, 0.3)\"),\n (\"친ꡬ의 고민을 ν•΄κ²°ν•΄μ£ΌλŠ” μ—­ν• κ·Ήμ—μ„œ μƒλŒ€λ°©μ„ λ°°λ €ν•˜μ—¬ ν•΄κ²° κ°€λŠ₯ν•œ λ°©μ•ˆμ„ μ œμ•ˆν•¨.\", \"μˆ˜ν–‰\", \"rgba(0, 128, 0, 0.3)\"),\n (\"μƒλŒ€κ°€ μ²˜ν•œ 상황을 μ΄ν•΄ν•˜κ³  κ³΅κ°ν•˜λŠ” νƒœλ„λ₯Ό 가지고 μΉœκ΅¬λ“€κ³Ό μ›λ§Œν•œ 관계λ₯Ό λ§Ίκ³  κ°ˆλ“±μ„ 쑰정함.\", \"ꡐ사총평\", \"rgba(128, 128, 128, 0.3)\"),\n (\"쀑간 놀이 μ‹œκ°„μ— μš΄λ™μž₯을 μ‚¬μš©ν•˜λŠ” 방법 μ •ν•˜κΈ°λ₯Ό 주제둜 ν•œ ν† μ˜μ—μ„œ μ•Œλ§žμ€ 근거와 λ’·λ°›μΉ¨ν•  수 μžˆλŠ” 자료λ₯Ό ν† λŒ€λ‘œ μžμ‹ μ˜ μ˜κ²¬μ„ νƒ€λ‹Ήν•˜κ²Œ μ œμ‹œν•˜λ©΄μ„œ λ‹€λ₯Έ μ‚¬λžŒμ˜ μ˜κ²¬μ„ λŠ₯λ™μ μœΌλ‘œ μˆ˜μš©ν•˜κ³  효과적으둜 μ˜κ²¬μ„ μ‘°μ •ν•˜λŠ” λŠ₯λ ₯을 λ³΄μž„.\", \"μˆ˜ν–‰\", \"rgba(0, 128, 0, 0.3)\"),\n (\"μƒλŒ€μ˜ μ˜κ²¬μ„ μ‘΄μ€‘ν•˜κ³  ν˜‘λ ₯ν•˜λŠ” νƒœλ„λ₯Ό λ³΄μž„.\", \"μ—­λŸ‰\", \"rgba(255, 0, 0, 0.3)\")\n)\n```"
},
{
"role": "user",
"content": text
}
],
temperature=1,
max_tokens=10000,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
return response['choices'][0]['message']['content']
# μœ μ‚¬ν•œ λ¬Έμž₯ 생성 ν•¨μˆ˜
def generate_similar_sentences(base_sentence):
response = openai.ChatCompletion.create(
model="gpt-4o-mini",
messages=[
{
"role": "system",
"content": f"""λ‹€μŒ 기쀀을 따라 '{base_sentence}'와 μœ μ‚¬ν•˜μ§€λ§Œ 독창적인 학생 평가 문ꡬ 30개λ₯Ό 생성해 μ£Όμ„Έμš”:
1. μ£Όμ–΄λŠ” μƒλž΅ν•˜κ³  μ„œμˆ μ–΄λ‘œ μ‹œμž‘ν•©λ‹ˆλ‹€.
2. λ¬Έμž₯ 끝은 '~μž„', '~함', '~음' λ“± λ‹€μ–‘ν•œ μ’…κ²°μ–΄λ―Έλ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.
3. μ›λž˜ λ¬Έμž₯의 핡심 μ˜λ―ΈλŠ” μœ μ§€ν•˜λ˜, λ‹€μŒ μš”μ†Œλ“€μ„ λ³€ν˜•ν•˜μ—¬ 닀양성을 λ†’μž…λ‹ˆλ‹€:
- μœ μ‚¬ν•œ 의미의 λ‹€λ₯Έ λ‹¨μ–΄λ‚˜ ν‘œν˜„ μ‚¬μš©
- λ¬Έμž₯ ꡬ쑰 λ³€κ²½ (예: λŠ₯λ™νƒœ/μˆ˜λ™νƒœ μ „ν™˜)
- ꡬ체적인 μ˜ˆμ‹œλ‚˜ 상황 μΆ”κ°€
- 뢀사어ꡬλ₯Ό μΆ”κ°€ν•˜μ—¬ 의미 ν™•μž₯
4. ν•™μƒμ˜ μ„±μž₯κ³Ό λ°œμ „μ„ κΈμ •μ μœΌλ‘œ ν‘œν˜„ν•©λ‹ˆλ‹€.
5. ꡐ과 κ΄€λ ¨ μ—­λŸ‰, μ°½μ˜μ„±, ν˜‘λ™μ‹¬, 리더십 λ“± λ‹€μ–‘ν•œ 츑면을 κ³ λ €ν•©λ‹ˆλ‹€.
6. νŠΉμ • ν•™λ…„μ΄λ‚˜ κ³Όλͺ©μ— κ΅­ν•œλ˜μ§€ μ•Šλ„λ‘ μΌλ°˜ν™”ν•©λ‹ˆλ‹€.
7. 각 λ¬Έκ΅¬λŠ” μ΅œμ†Œ 20자 이상, μ΅œλŒ€ 100자 μ΄λ‚΄λ‘œ μž‘μ„±ν•©λ‹ˆλ‹€.
μƒμ„±λœ 문ꡬ듀은 μ›λž˜ λ¬Έμž₯κ³Ό μœ μ‚¬ν•˜λ©΄μ„œλ„ μΆ©λΆ„νžˆ λ‹€μ–‘ν•˜κ³  독창적이어야 ν•©λ‹ˆλ‹€."""
},
{
"role": "user",
"content": base_sentence
}
],
temperature=0.7,
max_tokens=10000,
top_p=1,
frequency_penalty=0,
presence_penalty=0
)
generated_sentences = response.choices[0].message['content'].split('\n')
return [sentence.strip() for sentence in generated_sentences if sentence.strip()]
# Streamlit μ•±μ˜ 제λͺ© 및 μ„€λͺ…
st.title("μ„±μ·¨κΈ°μ€€ 기반 ν•™μƒμ˜ νŠΉμ„± 및 ν™œλ™ 평가 생성")
st.write("성취기쀀을 μž…λ ₯ν•˜μ‹œλ©΄, ν•΄λ‹Ή 성취기쀀에 κΈ°λ°˜ν•œ ν•™μƒμ˜ νŠΉμ„± 및 ν™œλ™μ— λŒ€ν•œ 평가λ₯Ό \n\n [학생 ν™œλ™, μ„±μ·¨ μˆ˜μ€€, κ΅μ‚¬μ˜ 총평, 학생 μ—­λŸ‰] 4가지 μš”μ†Œλ₯Ό μ‘°ν•©ν•˜μ—¬ μ œκ³΅ν•©λ‹ˆλ‹€.")
# μ„±μ·¨κΈ°μ€€ 데이터 κ°€μ Έμ˜€κΈ°
achievement_standards = data.achievement_standards
# ν•™λ…„κ΅° 선택 λ“œλ‘­λ‹€μš΄
grade_group = st.selectbox("학년ꡰ을 μ„ νƒν•˜μ„Έμš”:", list(achievement_standards.keys()))
# μ„ νƒλœ 학년ꡰ에 λ”°λ₯Έ κ³Όλͺ© λͺ©λ‘
subject_list = list(achievement_standards[grade_group].keys())
subject = st.selectbox("κ³Όλͺ©μ„ μ„ νƒν•˜μ„Έμš”:", subject_list)
# μ„ νƒλœ κ³Όλͺ©μ— λ”°λ₯Έ μ„±μ·¨κΈ°μ€€ λͺ©λ‘
selected_standards = achievement_standards[grade_group][subject]
selected_standard = st.selectbox("성취기쀀을 μ„ νƒν•˜μ„Έμš”:", selected_standards)
# μ„ νƒλœ 성취기쀀을 ν…μŠ€νŠΈ μž…λ ₯창의 κΈ°λ³Έκ°’μœΌλ‘œ μ‚¬μš©
achievement_standard = st.text_input("μ„±μ·¨κΈ°μ€€ μž…λ ₯:", value=selected_standard)
# μ„Έμ…˜ μƒνƒœ μ΄ˆκΈ°ν™”
if 'generated_result' not in st.session_state:
st.session_state.generated_result = None
if 'selected_sentence' not in st.session_state:
st.session_state.selected_sentence = None
if 'similar_sentences' not in st.session_state:
st.session_state.similar_sentences = []
# "평가 생성" λ²„νŠΌ 클릭 μ‹œμ˜ λ™μž‘
if st.button("평가 생성"):
with st.spinner('λ‹΅λ³€ 생성쀑...'):
result = generate_annotated_text(achievement_standard)
st.session_state.generated_result = result
st.session_state.selected_sentence = None # μƒˆλ‘œμš΄ 평가 μƒμ„±μ‹œ μ„ νƒλœ λ¬Έμž₯ μ΄ˆκΈ°ν™”
st.session_state.similar_sentences = [] # 이전 μœ μ‚¬ν•œ λ¬Έμž₯λ“€ μ΄ˆκΈ°ν™”
exec(result.replace('```', ''))
# μ…€λ ‰νŠΈ λ°•μŠ€ 및 μœ μ‚¬ν•œ λ¬Έμž₯ 생성 λ²„νŠΌ μΆ”κ°€
if st.session_state.generated_result:
# annotated_text κ²°κ³Όμ—μ„œ λ¬Έμž₯만 μΆ”μΆœ
result_lines = st.session_state.generated_result.split('\n')
sentences = [line[start_idx + 2:line.find('",', start_idx)].strip() for line in result_lines if (start_idx := line.find('("')) != -1]
if sentences:
selected_sentence = st.selectbox("λ¬Έμž₯을 μ„ νƒν•˜μ„Έμš”:", sentences, key="sentence_select")
st.session_state.selected_sentence = selected_sentence
# μœ μ‚¬ν•œ λ¬Έμž₯ 생성 λ²„νŠΌ
if st.button("μœ μ‚¬ν•œ 문ꡬ 생성") and st.session_state.selected_sentence:
with st.spinner('λ¬Έμž₯ 생성쀑...'):
st.session_state.similar_sentences = generate_similar_sentences(st.session_state.selected_sentence)
# μœ μ‚¬ν•œ λ¬Έμž₯λ“€ 좜λ ₯
for sentence in st.session_state.similar_sentences:
st.write(sentence)
# CSV 파일둜 μ €μž₯ν•˜λŠ” λ²„νŠΌ μΆ”κ°€
if st.session_state.similar_sentences:
# λ°μ΄ν„°ν”„λ ˆμž„ 생성
df = pd.DataFrame(st.session_state.similar_sentences, columns=["Similar Sentences"])
# UTF-8-SIG (BOM) μΈμ½”λ”©μœΌλ‘œ CSV 파일 λ³€ν™˜
csv = df.to_csv(index=False, encoding='utf-8-sig').encode('utf-8-sig')
# λ‹€μš΄λ‘œλ“œ λ²„νŠΌ 생성
st.download_button(
label="CSV둜 μ €μž₯",
data=csv,
file_name='similar_sentences.csv',
mime='text/csv'
)