File size: 7,913 Bytes
71bfdcb
7a3d92d
829f184
7a3d92d
cc9698d
22b626b
7a3d92d
86f45ae
 
7a3d92d
 
f4de003
22b626b
829f184
 
c4bc644
7a3d92d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
829f184
 
 
123222c
9447f48
 
7fc494d
123222c
9447f48
 
ed449f1
 
7c5c1ee
ed449f1
 
 
 
 
 
 
 
7c5c1ee
ed449f1
 
123222c
 
 
 
9447f48
 
123222c
9447f48
 
 
 
 
123222c
 
22b626b
71bfdcb
 
7a3d92d
 
 
 
71bfdcb
 
 
 
 
 
 
2c8f446
71bfdcb
 
 
32170e5
71bfdcb
 
829f184
71bfdcb
 
 
 
 
 
 
 
 
 
 
7a3d92d
71bfdcb
 
 
 
 
 
 
 
 
bca9727
7a3d92d
71bfdcb
 
 
 
 
 
 
 
 
 
 
 
22b626b
 
 
 
 
 
d4ebf2c
 
22b626b
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
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'
        )