read / app.py
ll7098ll's picture
Update app.py
fd17318 verified
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
# Google Gemini API 값 설정
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
# Markdown to HTML 변환
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
# Streamlit 인터페이스 설정
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)