ginipick commited on
Commit
d479d1a
ยท
verified ยท
1 Parent(s): c9beceb

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +31 -240
app.py CHANGED
@@ -1,244 +1,35 @@
1
- import streamlit as st
2
- from langchain.prompts import PromptTemplate
3
- from langchain.chains import LLMChain
4
- from langchain_google_genai import ChatGoogleGenerativeAI
5
- import fitz
6
- import json
7
- import docx
8
  import os
 
 
 
9
 
10
-
11
- # Session states
12
- if "mcqs" not in st.session_state:
13
- st.session_state.mcqs = []
14
- if "current_q" not in st.session_state:
15
- st.session_state.current_q = 0
16
- if "user_answers" not in st.session_state:
17
- st.session_state.user_answers = {}
18
- if "quiz_finished" not in st.session_state:
19
- st.session_state.quiz_finished = False
20
- if "language" not in st.session_state:
21
- st.session_state.language = "English"
22
-
23
- # Language selection in sidebar
24
- st.sidebar.title("๐ŸŒ Language / ์–ธ์–ด")
25
- language = st.sidebar.selectbox(
26
- "Select Language / ์–ธ์–ด ์„ ํƒ",
27
- ["English", "ํ•œ๊ตญ์–ด"],
28
- index=0 if st.session_state.language == "English" else 1
29
- )
30
- st.session_state.language = language
31
-
32
- # UI Text Dictionary
33
- ui_text = {
34
- "English": {
35
- "title": "๐Ÿ“„ File-based MCQ Generator",
36
- "sidebar_title": "Upload & Settings",
37
- "upload_prompt": "Upload a file (PDF or Word)",
38
- "num_questions": "Number of questions",
39
- "generate_button": "Generate MCQs",
40
- "no_file_error": "Please upload a file.",
41
- "generating": "Extracting text and generating MCQs...",
42
- "success": "โœ… MCQs generated successfully!",
43
- "error": "Error generating MCQs:",
44
- "question_prefix": "Question",
45
- "choose_answer": "Choose an answer:",
46
- "next_button": "Next",
47
- "quiz_completed": "๐ŸŽ‰ Quiz completed!",
48
- "results_header": "๐Ÿ“Š Quiz Results",
49
- "your_answer": "Your answer:",
50
- "correct_answer": "Correct answer:",
51
- "score": "โœ… You scored {score} out of {total}"
52
- },
53
- "ํ•œ๊ตญ์–ด": {
54
- "title": "๐Ÿ“„ ํŒŒ์ผ ๊ธฐ๋ฐ˜ ๊ฐ๊ด€์‹ ๋ฌธ์ œ ์ƒ์„ฑ๊ธฐ",
55
- "sidebar_title": "ํŒŒ์ผ ์—…๋กœ๋“œ ๋ฐ ์„ค์ •",
56
- "upload_prompt": "ํŒŒ์ผ ์—…๋กœ๋“œ (PDF ๋˜๋Š” Word)",
57
- "num_questions": "๋ฌธ์ œ ๊ฐœ์ˆ˜",
58
- "generate_button": "๋ฌธ์ œ ์ƒ์„ฑ",
59
- "no_file_error": "ํŒŒ์ผ์„ ์—…๋กœ๋“œํ•ด์ฃผ์„ธ์š”.",
60
- "generating": "ํ…์ŠคํŠธ ์ถ”์ถœ ๋ฐ ๋ฌธ์ œ ์ƒ์„ฑ ์ค‘...",
61
- "success": "โœ… ๋ฌธ์ œ๊ฐ€ ์„ฑ๊ณต์ ์œผ๋กœ ์ƒ์„ฑ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!",
62
- "error": "๋ฌธ์ œ ์ƒ์„ฑ ์˜ค๋ฅ˜:",
63
- "question_prefix": "๋ฌธ์ œ",
64
- "choose_answer": "๋‹ต์„ ์„ ํƒํ•˜์„ธ์š”:",
65
- "next_button": "๋‹ค์Œ",
66
- "quiz_completed": "๐ŸŽ‰ ํ€ด์ฆˆ๊ฐ€ ์™„๋ฃŒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค!",
67
- "results_header": "๐Ÿ“Š ํ€ด์ฆˆ ๊ฒฐ๊ณผ",
68
- "your_answer": "๋‹น์‹ ์˜ ๋‹ต:",
69
- "correct_answer": "์ •๋‹ต:",
70
- "score": "โœ… {total}๋ฌธ์ œ ์ค‘ {score}๋ฌธ์ œ๋ฅผ ๋งž์ถ”์…จ์Šต๋‹ˆ๋‹ค"
71
- }
72
- }
73
-
74
- # Get current language texts
75
- texts = ui_text[language]
76
-
77
- # Title
78
- st.title(texts["title"])
79
-
80
- # Sidebar
81
- st.sidebar.title(texts["sidebar_title"])
82
-
83
- # Upload file
84
- uploaded_file = st.sidebar.file_uploader(texts["upload_prompt"], type=["pdf", "docx"])
85
-
86
- # Number of questions
87
- number_of_questions = st.sidebar.slider(texts["num_questions"], min_value=1, max_value=20, value=5)
88
-
89
- # Gemini setup
90
- GOOGLE_API_KEY = os.getenv("GOOGLE_API_KEY")
91
- llm = ChatGoogleGenerativeAI(
92
- model="gemini-2.0-flash-exp",
93
- google_api_key=GOOGLE_API_KEY,
94
- temperature=0.7
95
- )
96
-
97
- # Templates for different languages
98
- template_english = """
99
- You are an expert MCQ generator. Generate {number} unique multiple-choice questions from the given text.
100
- Each question must have exactly 1 correct answer and 3 incorrect options.
101
- Strictly return output in the following JSON format (no explanations, no markdown):
102
-
103
- [
104
- {{
105
- "question": "What is ...?",
106
- "options": ["Option A", "Option B", "Option C", "Option D"],
107
- "answer": "Option D"
108
- }},
109
- ...
110
- ]
111
-
112
- TEXT:
113
- {text}
114
- """
115
-
116
- template_korean = """
117
- ๋‹น์‹ ์€ ์ „๋ฌธ ๊ฐ๊ด€์‹ ๋ฌธ์ œ ์ถœ์ œ์ž์ž…๋‹ˆ๋‹ค. ์ฃผ์–ด์ง„ ํ…์ŠคํŠธ์—์„œ {number}๊ฐœ์˜ ๊ณ ์œ ํ•œ ๊ฐ๊ด€์‹ ๋ฌธ์ œ๋ฅผ ์ƒ์„ฑํ•˜์„ธ์š”.
118
- ๊ฐ ๋ฌธ์ œ๋Š” ์ •ํ™•ํžˆ 1๊ฐœ์˜ ์ •๋‹ต๊ณผ 3๊ฐœ์˜ ์˜ค๋‹ต์„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
119
- ๋‹ค์Œ JSON ํ˜•์‹์œผ๋กœ๋งŒ ์ถœ๋ ฅํ•˜์„ธ์š” (์„ค๋ช…์ด๋‚˜ ๋งˆํฌ๋‹ค์šด ์—†์ด):
120
-
121
- [
122
- {{
123
- "question": "...๋Š” ๋ฌด์—‡์ž…๋‹ˆ๊นŒ?",
124
- "options": ["์„ ํƒ์ง€ A", "์„ ํƒ์ง€ B", "์„ ํƒ์ง€ C", "์„ ํƒ์ง€ D"],
125
- "answer": "์„ ํƒ์ง€ D"
126
- }},
127
- ...
128
- ]
129
-
130
- ํ…์ŠคํŠธ:
131
- {text}
132
- """
133
-
134
- # Select template based on language
135
- template = template_english if language == "English" else template_korean
136
-
137
- prompt = PromptTemplate(
138
- input_variables=["text", "number"],
139
- template=template
140
- )
141
-
142
- mcq_chain = LLMChain(llm=llm, prompt=prompt)
143
-
144
- # Extract text from PDF or Word
145
- def extract_text(file):
146
- if file.name.endswith(".pdf"):
147
- # Read the entire file content into memory
148
- file_bytes = file.read()
149
- # Open the PDF from the byte stream
150
- doc = fitz.open(stream=file_bytes, filetype="pdf")
151
- # Extract text from all pages
152
- text = ""
153
- for page in doc:
154
- text += page.get_text()
155
- return text
156
- elif file.name.endswith(".docx"):
157
- doc = docx.Document(file)
158
- return "\n".join([para.text for para in doc.paragraphs])
159
- return ""
160
-
161
- # Generate MCQs
162
- if st.sidebar.button(texts["generate_button"]):
163
- if uploaded_file is None:
164
- st.error(texts["no_file_error"])
165
- else:
166
- with st.spinner(texts["generating"]):
167
- text = extract_text(uploaded_file)
168
- try:
169
- response = mcq_chain.run(text=text, number=str(number_of_questions))
170
- # Clean the response to extract JSON
171
- response = response.strip()
172
- if response.startswith("```json"):
173
- response = response[7:]
174
- if response.endswith("```"):
175
- response = response[:-3]
176
- mcqs_json = json.loads(response)
177
- st.session_state.mcqs = mcqs_json
178
- st.session_state.current_q = 0
179
- st.session_state.user_answers = {}
180
- st.session_state.quiz_finished = False
181
- st.success(texts["success"])
182
- except Exception as e:
183
- st.error(f"{texts['error']} {e}")
184
-
185
- # Display question
186
- if st.session_state.mcqs and not st.session_state.quiz_finished:
187
- idx = st.session_state.current_q
188
- q_data = st.session_state.mcqs[idx]
189
-
190
- st.subheader(f"{texts['question_prefix']} {idx + 1}: {q_data['question']}")
191
-
192
- with st.form(key=f"form_{idx}"):
193
- selected_option = st.radio(texts["choose_answer"], q_data["options"], key=f"radio_{idx}")
194
- submitted = st.form_submit_button(texts["next_button"])
195
-
196
- if submitted:
197
- st.session_state.user_answers[idx] = selected_option
198
- if idx < len(st.session_state.mcqs) - 1:
199
- st.session_state.current_q += 1
200
- st.rerun()
201
- else:
202
- st.session_state.quiz_finished = True
203
- st.success(texts["quiz_completed"])
204
- st.rerun()
205
-
206
- # Show result
207
- if st.session_state.quiz_finished:
208
- st.header(texts["results_header"])
209
- score = 0
210
- total = len(st.session_state.mcqs)
211
-
212
- for i, q in enumerate(st.session_state.mcqs):
213
- user_ans = st.session_state.user_answers.get(i)
214
- correct_ans = q["answer"]
215
- if user_ans == correct_ans:
216
- score += 1
217
 
218
- # Question display
219
- st.markdown(f"**{texts['question_prefix']}{i+1}: {q['question']}**")
 
220
 
221
- # Answers with color coding
222
- if user_ans == correct_ans:
223
- st.markdown(f"- {texts['your_answer']} :green[{user_ans}] โœ“")
224
- else:
225
- st.markdown(f"- {texts['your_answer']} :red[{user_ans}] โœ—")
226
- st.markdown(f"- {texts['correct_answer']} :green[{correct_ans}]")
227
- st.markdown("---")
228
-
229
- # Score display
230
- score_text = texts["score"].format(score=score, total=total)
231
- st.success(score_text)
232
-
233
- # Reset button
234
- if language == "English":
235
- reset_text = "Start New Quiz"
236
- else:
237
- reset_text = "์ƒˆ ํ€ด์ฆˆ ์‹œ์ž‘"
238
-
239
- if st.button(reset_text):
240
- st.session_state.mcqs = []
241
- st.session_state.current_q = 0
242
- st.session_state.user_answers = {}
243
- st.session_state.quiz_finished = False
244
- st.rerun()
 
 
 
 
 
 
 
 
1
  import os
2
+ import sys
3
+ import streamlit as st
4
+ from tempfile import NamedTemporaryFile
5
 
6
+ def main():
7
+ try:
8
+ # Get the code from secrets
9
+ code = os.environ.get("MAIN_CODE")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
10
 
11
+ if not code:
12
+ st.error("โš ๏ธ The application code wasn't found in secrets. Please add the MAIN_CODE secret.")
13
+ return
14
 
15
+ # Create a temporary Python file
16
+ with NamedTemporaryFile(suffix='.py', delete=False, mode='w') as tmp:
17
+ tmp.write(code)
18
+ tmp_path = tmp.name
19
+
20
+ # Execute the code
21
+ exec(compile(code, tmp_path, 'exec'), globals())
22
+
23
+ # Clean up the temporary file
24
+ try:
25
+ os.unlink(tmp_path)
26
+ except:
27
+ pass
28
+
29
+ except Exception as e:
30
+ st.error(f"โš ๏ธ Error loading or executing the application: {str(e)}")
31
+ import traceback
32
+ st.code(traceback.format_exc())
33
+
34
+ if __name__ == "__main__":
35
+ main()