|
|
import os |
|
|
import time |
|
|
import google.generativeai as genai |
|
|
import streamlit as st |
|
|
from streamlit_extras.colored_header import colored_header |
|
|
from streamlit_extras.add_vertical_space import add_vertical_space |
|
|
import markdown |
|
|
|
|
|
|
|
|
genai.configure(api_key=os.environ["GEMINI_API_KEY"]) |
|
|
|
|
|
|
|
|
generation_config = { |
|
|
"temperature": 0.7, |
|
|
"top_p": 0.95, |
|
|
"top_k": 64, |
|
|
"max_output_tokens": 8000, |
|
|
"response_mime_type": "text/plain", |
|
|
} |
|
|
|
|
|
model = genai.GenerativeModel( |
|
|
model_name="gemini-2.5-flash", |
|
|
generation_config=generation_config, |
|
|
) |
|
|
|
|
|
def generate_text(grade, num_paragraphs, sentences_per_paragraph, structure, topic): |
|
|
""" |
|
|
주어진 조건에 따라 설명문 텍스트, 어휘 목록, 독해 문제를 생성하고 스트리밍으로 출력합니다. |
|
|
""" |
|
|
|
|
|
prompt = f""" |
|
|
# 지시사항 |
|
|
## 1. 설명문 작성 |
|
|
- **대상 독자:** 초등학교 {grade} 학생 |
|
|
- **주제:** '{topic}' |
|
|
- **글의 구조:** '{structure}' 구조를 명확히 따를 것 |
|
|
- **분량:** 전체 {num_paragraphs}개 문단 내외, 문단 당 {sentences_per_paragraph}개 문장 내외 |
|
|
- **스타일:** |
|
|
- 초등학생이 이해하기 쉬운 단어와 문장 사용 |
|
|
- 줄글 형식으로 작성, 문단 구분 명확히 (빈 줄 사용) |
|
|
- 각 문단의 첫 문장 또는 마지막 문장이 중심 문장이 되도록 작성 |
|
|
- **제목:** 글의 맨 처음에 내용을 잘 나타내는 제목을 **크고 굵은 글씨**로 작성 (Markdown 형식: '** 제목 **') |
|
|
## 2. 어휘 목록 작성 |
|
|
- **선정 기준:** 본문 내용 중 초등학교 {grade}에게 어려울 수 있는 단어, 한자어, 학습 용어 |
|
|
- **설명 방식:** 해당 학년 수준에 맞는 쉬운 유의어 또는 풀이 제공 |
|
|
- **형식:** 설명문 본문 뒤에 '### 어휘 목록' 제목 아래 글머리 기호 목록으로 작성 |
|
|
```markdown |
|
|
### 어휘 목록 |
|
|
* 단어1: 쉬운 설명/유의어 |
|
|
* 단어2: 쉬운 설명/유의어 |
|
|
... |
|
|
``` |
|
|
## 3. 독해 문제 및 정답 출제 |
|
|
- **출제 기반:** **반드시 위에서 생성된 설명문 내용만을 바탕으로** 출제 |
|
|
- **문제 수:** 총 7~8개 |
|
|
- **문제 유형 (균형 있게 포함):** |
|
|
- **사실적 이해:** 글에 명시된 정보 확인 (누가, 무엇을, 언제, 어디서 등) |
|
|
- **추론적 이해:** 글에 명시되지 않았지만 내용을 바탕으로 논리적으로 판단 가능한 내용 (왜, 그래서 어떻게 될까 등) |
|
|
- **어휘:** 본문 또는 어휘 목록에 나온 단어의 문맥상 의미 파악 |
|
|
- **글의 구조:** 글 전체의 짜임, 문단 간 관계, 사용된 설명 방식 등 파악 |
|
|
- **문제 형식 (혼합 사용):** |
|
|
- **단답형:** 간단한 단어, 구, 짧은 문장으로 답하는 문제 |
|
|
- **5지 선다형:** 5개의 선택지(①, ②, ③, ④, ⑤) 중 정답을 고르는 문제 (오답 선택지도 그럴듯하게 구성) |
|
|
- **형식:** |
|
|
- '### 독해 문제' 제목 아래 문제 번호(1., 2., ...)와 함께 문제 제시 |
|
|
- 모든 문제 출제 후, '### 정답' 제목 아래 문제 번호와 정답 명확히 제시 |
|
|
```markdown |
|
|
### 독해 문제 |
|
|
1. [문제 내용 - 단답형 또는 5지 선다형] |
|
|
① 선택지1 ② 선택지2 ③ 선택지3 ④ 선택지4 ⑤ 선택지5 (선다형의 경우) |
|
|
2. [문제 내용 - 단답형 또는 5지 선다형] |
|
|
... (총 7~8개) |
|
|
### 정답 |
|
|
1. [정답 내용 또는 번호] |
|
|
2. [정답 내용 또는 번호] |
|
|
... |
|
|
``` |
|
|
## # 출력 요구사항 |
|
|
- 위의 모든 지시사항(설명문, 어휘 목록, 독해 문제, 정답)을 **하나의 응답**으로 이어서 생성해주세요. |
|
|
- 각 섹션(제목, 본문, 어휘 목록, 독해 문제, 정답) 구분을 Markdown 제목(##, ###)과 빈 줄로 명확히 해주세요. |
|
|
- 모든 내용은 초등학교 {grade} 눈높이에 맞춰 작성해주세요.""" |
|
|
|
|
|
full_text = "" |
|
|
try: |
|
|
response = model.generate_content(prompt, stream=True) |
|
|
for chunk in response: |
|
|
full_text += chunk.text |
|
|
|
|
|
html_text = markdown.markdown(full_text, extensions=['tables']) |
|
|
output_area.markdown(html_text, unsafe_allow_html=True) |
|
|
time.sleep(0.1) |
|
|
|
|
|
except Exception as e: |
|
|
st.error(f"에러 발생: {str(e)}") |
|
|
return "" |
|
|
|
|
|
|
|
|
|
|
|
copy_button = st.button("출력 내용 복사") |
|
|
if copy_button: |
|
|
pyperclip.copy(full_text) |
|
|
st.success("클립보드에 복사되었습니다!") |
|
|
|
|
|
return full_text |
|
|
|
|
|
|
|
|
|
|
|
colored_header( |
|
|
label="📜 초등학생을 위한 읽기 자료 생성기", |
|
|
description="주제를 입력하면 초등학생이 이해하기 쉬운 읽기 자료를 만들어줍니다.", |
|
|
color_name="red-70", |
|
|
) |
|
|
|
|
|
add_vertical_space(1) |
|
|
|
|
|
with st.sidebar: |
|
|
st.header("옵션 설정") |
|
|
grade = st.selectbox("학년", [f"초등학교 {i}학년" for i in range(1, 7)]) |
|
|
num_paragraphs = st.number_input("문단 수", min_value=1, value=3) |
|
|
sentences_per_paragraph = st.number_input("문단 당 문장 수", min_value=1, value=3) |
|
|
structure = st.selectbox("설명문 구조", ["정의와 예시", "비교와 대조", "분류", "분석", "인과", "순서"], index=0) |
|
|
topic = st.text_area("✏️ 주제 및 내용을 입력하세요 ", height=200) |
|
|
|
|
|
generate_button = st.button("읽기 자료 생성") |
|
|
|
|
|
|
|
|
output_area = st.empty() |
|
|
|
|
|
|
|
|
if generate_button: |
|
|
generate_text(grade, num_paragraphs, sentences_per_paragraph, structure, topic) |