joshuarauh commited on
Commit
6e9b3c0
·
verified ·
1 Parent(s): 2a474e7

one q only

Browse files
Files changed (1) hide show
  1. app.py +41 -122
app.py CHANGED
@@ -96,28 +96,15 @@ def create_latex_document(content, questions_only=False):
96
  \usepackage{amsmath,amssymb}
97
  \usepackage[margin=1in]{geometry}
98
  \begin{document}
99
- \title{Mathematics Test}
100
  \maketitle
101
  """
102
  latex_footer = r"\end{document}"
103
 
104
  if questions_only:
105
- processed_content = []
106
- current_question = []
107
- for line in content.split('\n'):
108
- if 'Solution:' in line:
109
- processed_content.append('\n'.join(current_question))
110
- current_question = []
111
- continue
112
- if any(line.startswith(f"{i})") for i in range(1, 4)):
113
- if current_question:
114
- processed_content.append('\n'.join(current_question))
115
- current_question = [line]
116
- elif current_question:
117
- current_question.append(line)
118
- if current_question:
119
- processed_content.append('\n'.join(current_question))
120
- content = '\n\n'.join(processed_content)
121
 
122
  full_document = f"{latex_header}\n{content}\n{latex_footer}"
123
  logger.debug(f"Created {'questions-only' if questions_only else 'full'} LaTeX document")
@@ -129,52 +116,24 @@ def create_latex_document(content, questions_only=False):
129
  def save_to_temp_file(content, filename):
130
  """Save content to a temporary file and return the path"""
131
  try:
132
- # Create a temporary directory that persists
133
  temp_dir = Path(tempfile.gettempdir()) / "math_test_files"
134
  temp_dir.mkdir(exist_ok=True)
135
-
136
- # Create the file path
137
  file_path = temp_dir / filename
138
-
139
- # Write the content
140
  file_path.write_text(content, encoding='utf-8')
141
-
142
  logger.debug(f"Saved content to temporary file: {file_path}")
143
  return str(file_path)
144
  except Exception as e:
145
  logger.error(f"Error saving temporary file: {str(e)}")
146
  raise
147
 
148
- def validate_question_counts(computation, proof, application):
149
- """Validate that question counts sum to 3"""
150
  try:
151
- comp = int(computation)
152
- prf = int(proof)
153
- app = int(application)
154
-
155
- if comp + prf + app != 3:
156
- return False, "Total number of questions must equal 3"
157
- if any(x < 0 for x in [comp, prf, app]):
158
- return False, "Question counts cannot be negative"
159
- return True, ""
160
- except ValueError:
161
- return False, "Please enter valid numbers"
162
-
163
- def generate_test(subject, difficulty, computation_count, proof_count, application_count):
164
- """Generate a math test with enhanced difficulty scaling"""
165
- try:
166
- # Validate inputs
167
- is_valid, error_message = validate_question_counts(
168
- computation_count, proof_count, application_count
169
- )
170
- if not is_valid:
171
- return error_message, None, None
172
-
173
  if not os.environ.get('ANTHROPIC_API_KEY'):
174
  logger.error("Anthropic API key not found")
175
  return "Error: Anthropic API key not configured", None, None
176
 
177
- logger.debug(f"Generating test for subject: {subject} at difficulty level: {difficulty}")
178
 
179
  # Check rate limit
180
  now = datetime.now()
@@ -191,29 +150,18 @@ def generate_test(subject, difficulty, computation_count, proof_count, applicati
191
  "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
192
  }
193
 
194
- selected_topics = random.sample(topics.get(subject, ["general"]), min(3, len(topics.get(subject, ["general"]))))
195
- logger.debug(f"Selected topics: {selected_topics}")
196
-
197
- # Create question type list based on user input
198
- question_types = (
199
- ["computation"] * int(computation_count) +
200
- ["proof"] * int(proof_count) +
201
- ["application"] * int(application_count)
202
- )
203
 
204
  difficulty_params = get_difficulty_parameters(difficulty)
205
 
206
  # Enhanced prompt for difficulty level 5
207
  if difficulty == 5:
208
- system_prompt = f"""You are an expert mathematics professor creating graduate-level exam questions.
209
-
210
  STRICT REQUIREMENTS:
211
- 1. Write exactly 3 graduate-level questions on {subject} with these specific characteristics:
212
- - Question Types (in order): {', '.join(question_types)}
213
- - Topics to cover: {', '.join(selected_topics)}
214
-
215
  2. Advanced Difficulty Requirements:
216
- These questions must be suitable for PhD qualifying exams or advanced competitions.
217
  MUST include:
218
  - Novel applications of theoretical concepts
219
  - Graduate-level mathematical reasoning
@@ -223,50 +171,37 @@ STRICT REQUIREMENTS:
223
 
224
  Follow these specific constraints:
225
  {chr(10).join(f' - {c}' for c in difficulty_params['constraints'])}
226
-
227
  3. Style Reference:
228
- Questions should be {difficulty_params['example_style']}
229
-
230
- 4. Each question MUST:
231
  - Bridge multiple mathematical domains
232
  - Require deep theoretical understanding
233
  - Test mastery of advanced concepts
234
  - Demand innovative solution approaches
235
-
236
  5. For LaTeX formatting:
237
  - Use $ for inline math
238
  - Use $$ on separate lines for equations and solutions
239
  - Put each solution step on its own line in $$ $$
240
  - DO NOT use \\begin{{aligned}} or similar environments
241
-
242
- 6. Number questions as 1), 2), 3)
243
- 7. Include detailed solutions with thorough explanations of advanced concepts used
244
- 8. Maintain clear, precise formatting"""
245
  else:
246
- system_prompt = f"""You are an expert mathematics professor creating {difficulty_params['description']} exam questions.
247
-
248
  STRICT REQUIREMENTS:
249
- 1. Write exactly 3 university-level questions on {subject} with these specific characteristics:
250
- - Question Types (in order): {', '.join(question_types)}
251
- - Topics to cover: {', '.join(selected_topics)}
252
-
253
  2. Difficulty Level Guidelines:
254
  {difficulty_params['description'].upper()}
255
  Follow these specific constraints:
256
  {chr(10).join(f' - {c}' for c in difficulty_params['constraints'])}
257
-
258
  3. Style Reference:
259
- Questions should be {difficulty_params['example_style']}
260
-
261
  4. For LaTeX formatting:
262
  - Use $ for inline math
263
  - Use $$ on separate lines for equations and solutions
264
  - Put each solution step on its own line in $$ $$
265
  - DO NOT use \\begin{{aligned}} or similar environments
266
-
267
- 5. Number questions as 1), 2), 3)
268
- 6. Include detailed solutions
269
- 7. Maintain clear formatting"""
270
 
271
  logger.debug("Sending request to Anthropic API")
272
  message = anthropic.messages.create(
@@ -275,7 +210,7 @@ STRICT REQUIREMENTS:
275
  temperature=0.7,
276
  messages=[{
277
  "role": "user",
278
- "content": f"{system_prompt}\n\nWrite an exam for {subject}."
279
  }]
280
  )
281
 
@@ -291,22 +226,22 @@ STRICT REQUIREMENTS:
291
  full_latex = create_latex_document(response_text, questions_only=False)
292
 
293
  # Save to temporary files
294
- questions_path = save_to_temp_file(questions_latex, "questions.tex")
295
- full_path = save_to_temp_file(full_latex, "full_test.tex")
296
 
297
  logger.debug("Successfully created temporary files")
298
 
299
  return response_text, questions_path, full_path
300
 
301
  except Exception as e:
302
- logger.error(f"Error generating test: {str(e)}")
303
  return f"Error: {str(e)}", None, None
304
 
305
  # Create Gradio interface
306
  with gr.Blocks() as interface:
307
- gr.Markdown("# Advanced Mathematics Test Generator")
308
- gr.Markdown("""Generates unique university-level mathematics exam questions with solutions using Claude 3.
309
- Each test features different topics and difficulty levels. Limited to 25 requests per day.""")
310
 
311
  with gr.Row():
312
  with gr.Column():
@@ -324,7 +259,7 @@ with gr.Blocks() as interface:
324
  "Topology"
325
  ],
326
  label="Select Mathematics Subject",
327
- info="Choose a subject for the exam questions"
328
  )
329
 
330
  difficulty_slider = gr.Slider(
@@ -335,32 +270,18 @@ with gr.Blocks() as interface:
335
  label="Difficulty Level",
336
  info="1: Very Easy, 2: Easy, 3: Moderate, 4: Difficult, 5: Very Difficult"
337
  )
338
-
339
- with gr.Row():
340
- with gr.Column():
341
- computation_count = gr.Number(
342
- value=1,
343
- label="Number of Computation Questions",
344
- info="Enter the number of computation questions (total must be 3)",
345
- precision=0
346
- )
347
- proof_count = gr.Number(
348
- value=1,
349
- label="Number of Proof Questions",
350
- info="Enter the number of proof questions (total must be 3)",
351
- precision=0
352
- )
353
- application_count = gr.Number(
354
- value=1,
355
- label="Number of Application Questions",
356
- info="Enter the number of application questions (total must be 3)",
357
- precision=0
358
  )
359
 
360
- generate_btn = gr.Button("Generate Test")
361
 
362
  output_text = gr.Markdown(
363
- label="Generated Test Preview",
364
  latex_delimiters=[
365
  {"left": "$$", "right": "$$", "display": True},
366
  {"left": "$", "right": "$", "display": False}
@@ -368,17 +289,15 @@ with gr.Blocks() as interface:
368
  )
369
 
370
  with gr.Row():
371
- questions_file = gr.File(label="Questions Only (LaTeX)")
372
- full_file = gr.File(label="Full Test with Solutions (LaTeX)")
373
 
374
  generate_btn.click(
375
- generate_test,
376
  inputs=[
377
  subject_dropdown,
378
  difficulty_slider,
379
- computation_count,
380
- proof_count,
381
- application_count
382
  ],
383
  outputs=[output_text, questions_file, full_file]
384
  )
 
96
  \usepackage{amsmath,amssymb}
97
  \usepackage[margin=1in]{geometry}
98
  \begin{document}
99
+ \title{Mathematics Question}
100
  \maketitle
101
  """
102
  latex_footer = r"\end{document}"
103
 
104
  if questions_only:
105
+ # Modified to handle single question
106
+ processed_content = content.split('Solution:')[0]
107
+ content = processed_content
 
 
 
 
 
 
 
 
 
 
 
 
 
108
 
109
  full_document = f"{latex_header}\n{content}\n{latex_footer}"
110
  logger.debug(f"Created {'questions-only' if questions_only else 'full'} LaTeX document")
 
116
  def save_to_temp_file(content, filename):
117
  """Save content to a temporary file and return the path"""
118
  try:
 
119
  temp_dir = Path(tempfile.gettempdir()) / "math_test_files"
120
  temp_dir.mkdir(exist_ok=True)
 
 
121
  file_path = temp_dir / filename
 
 
122
  file_path.write_text(content, encoding='utf-8')
 
123
  logger.debug(f"Saved content to temporary file: {file_path}")
124
  return str(file_path)
125
  except Exception as e:
126
  logger.error(f"Error saving temporary file: {str(e)}")
127
  raise
128
 
129
+ def generate_question(subject, difficulty, question_type):
130
+ """Generate a single math question"""
131
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  if not os.environ.get('ANTHROPIC_API_KEY'):
133
  logger.error("Anthropic API key not found")
134
  return "Error: Anthropic API key not configured", None, None
135
 
136
+ logger.debug(f"Generating {question_type} question for subject: {subject} at difficulty level: {difficulty}")
137
 
138
  # Check rate limit
139
  now = datetime.now()
 
150
  "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
151
  }
152
 
153
+ selected_topic = random.choice(topics.get(subject, ["general"]))
154
+ logger.debug(f"Selected topic: {selected_topic}")
 
 
 
 
 
 
 
155
 
156
  difficulty_params = get_difficulty_parameters(difficulty)
157
 
158
  # Enhanced prompt for difficulty level 5
159
  if difficulty == 5:
160
+ system_prompt = f"""You are an expert mathematics professor creating a graduate-level exam question.
 
161
  STRICT REQUIREMENTS:
162
+ 1. Write exactly 1 graduate-level {question_type} question on {subject} covering {selected_topic}.
 
 
 
163
  2. Advanced Difficulty Requirements:
164
+ This question must be suitable for PhD qualifying exams or advanced competitions.
165
  MUST include:
166
  - Novel applications of theoretical concepts
167
  - Graduate-level mathematical reasoning
 
171
 
172
  Follow these specific constraints:
173
  {chr(10).join(f' - {c}' for c in difficulty_params['constraints'])}
 
174
  3. Style Reference:
175
+ Question should be {difficulty_params['example_style']}
176
+ 4. The question MUST:
 
177
  - Bridge multiple mathematical domains
178
  - Require deep theoretical understanding
179
  - Test mastery of advanced concepts
180
  - Demand innovative solution approaches
 
181
  5. For LaTeX formatting:
182
  - Use $ for inline math
183
  - Use $$ on separate lines for equations and solutions
184
  - Put each solution step on its own line in $$ $$
185
  - DO NOT use \\begin{{aligned}} or similar environments
186
+ 6. Include a detailed solution with thorough explanations of advanced concepts used
187
+ 7. Maintain clear, precise formatting"""
 
 
188
  else:
189
+ system_prompt = f"""You are an expert mathematics professor creating a {difficulty_params['description']} exam question.
 
190
  STRICT REQUIREMENTS:
191
+ 1. Write exactly 1 {question_type} question on {subject} covering {selected_topic}.
 
 
 
192
  2. Difficulty Level Guidelines:
193
  {difficulty_params['description'].upper()}
194
  Follow these specific constraints:
195
  {chr(10).join(f' - {c}' for c in difficulty_params['constraints'])}
 
196
  3. Style Reference:
197
+ Question should be {difficulty_params['example_style']}
 
198
  4. For LaTeX formatting:
199
  - Use $ for inline math
200
  - Use $$ on separate lines for equations and solutions
201
  - Put each solution step on its own line in $$ $$
202
  - DO NOT use \\begin{{aligned}} or similar environments
203
+ 5. Include a detailed solution
204
+ 6. Maintain clear formatting"""
 
 
205
 
206
  logger.debug("Sending request to Anthropic API")
207
  message = anthropic.messages.create(
 
210
  temperature=0.7,
211
  messages=[{
212
  "role": "user",
213
+ "content": f"{system_prompt}\n\nWrite a question for {subject}."
214
  }]
215
  )
216
 
 
226
  full_latex = create_latex_document(response_text, questions_only=False)
227
 
228
  # Save to temporary files
229
+ questions_path = save_to_temp_file(questions_latex, "question.tex")
230
+ full_path = save_to_temp_file(full_latex, "full_question.tex")
231
 
232
  logger.debug("Successfully created temporary files")
233
 
234
  return response_text, questions_path, full_path
235
 
236
  except Exception as e:
237
+ logger.error(f"Error generating question: {str(e)}")
238
  return f"Error: {str(e)}", None, None
239
 
240
  # Create Gradio interface
241
  with gr.Blocks() as interface:
242
+ gr.Markdown("# Advanced Mathematics Question Generator")
243
+ gr.Markdown("""Generates a unique university-level mathematics question with solution using Claude 3.
244
+ Each question features different topics and difficulty levels. Limited to 25 requests per day.""")
245
 
246
  with gr.Row():
247
  with gr.Column():
 
259
  "Topology"
260
  ],
261
  label="Select Mathematics Subject",
262
+ info="Choose a subject for the question"
263
  )
264
 
265
  difficulty_slider = gr.Slider(
 
270
  label="Difficulty Level",
271
  info="1: Very Easy, 2: Easy, 3: Moderate, 4: Difficult, 5: Very Difficult"
272
  )
273
+
274
+ question_type = gr.Radio(
275
+ choices=["computation", "proof", "application"],
276
+ label="Question Type",
277
+ info="Select the type of question you want",
278
+ value="computation"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
279
  )
280
 
281
+ generate_btn = gr.Button("Generate Question")
282
 
283
  output_text = gr.Markdown(
284
+ label="Generated Question Preview",
285
  latex_delimiters=[
286
  {"left": "$$", "right": "$$", "display": True},
287
  {"left": "$", "right": "$", "display": False}
 
289
  )
290
 
291
  with gr.Row():
292
+ questions_file = gr.File(label="Question Only (LaTeX)")
293
+ full_file = gr.File(label="Question with Solution (LaTeX)")
294
 
295
  generate_btn.click(
296
+ generate_question,
297
  inputs=[
298
  subject_dropdown,
299
  difficulty_slider,
300
+ question_type
 
 
301
  ],
302
  outputs=[output_text, questions_file, full_file]
303
  )