joshuarauh commited on
Commit
9682d40
·
verified ·
1 Parent(s): 4be1184

no conceptual questions, added download functionality

Browse files

Modified the system prompt to explicitly require computational or proof-based problems only, and explicitly forbid conceptual questions

Added functionality to generate both LaTeX and PDF versions of the test
Created a new interface using Gradio Blocks that includes:

Download buttons for questions-only and full test versions
Both LaTeX and PDF format options

Added functions to handle LaTeX document creation and PDF conversion
Improved the UI layout with separate sections for different download options

Files changed (1) hide show
  1. app.py +128 -52
app.py CHANGED
@@ -4,6 +4,9 @@ from anthropic import Anthropic
4
  from datetime import datetime, timedelta
5
  from collections import deque
6
  import random
 
 
 
7
 
8
  # Initialize Anthropic client
9
  anthropic = Anthropic(
@@ -31,8 +34,46 @@ def clean_latex(text):
31
  text = text.replace('\n', '\n\n')
32
  return text
33
 
34
- def generate_test(subject):
35
- """Generate a math test with enhanced variety"""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  try:
37
  check_api_key()
38
  if not check_rate_limit():
@@ -40,11 +81,10 @@ def generate_test(subject):
40
 
41
  request_history.append(datetime.now())
42
 
43
- # Randomly select focus areas and difficulty levels
44
  topics = {
45
  "Single Variable Calculus": ["limits", "derivatives", "integrals", "series", "applications"],
46
- "Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization", "surface integrals"],
47
- "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations", "inner products"],
48
  # ... add topics for other subjects
49
  }
50
 
@@ -58,8 +98,8 @@ def generate_test(subject):
58
  system_prompt = f"""You will write math exam questions. Follow these requirements EXACTLY:
59
  1. Write exactly 3 university-level questions focusing on these specific topics: {', '.join(selected_topics)}
60
  2. Make the questions {difficulty_distribution}
61
- 3. For each question, use a different type of mathematical thinking (e.g., computation, proof, application, conceptual understanding)
62
- 4. Ensure questions are unique and not commonly found in textbooks
63
  5. For LaTeX math formatting:
64
  - Use $ for simple inline math
65
  - For equations and solution steps, use $$ on separate lines
@@ -69,13 +109,9 @@ def generate_test(subject):
69
  7. Include detailed solutions after each question
70
  8. Keep formatting simple and clear
71
 
72
- Important: Make these questions distinct from standard textbook problems. Incorporate real-world applications,
73
- interdisciplinary connections, or creative scenarios where appropriate."""
74
 
75
- # Vary temperature based on subject complexity
76
- base_temperature = 0.7
77
- complexity_adjustment = random.uniform(-0.1, 0.1)
78
- temperature = min(1.0, max(0.5, base_temperature + complexity_adjustment))
79
 
80
  message = anthropic.messages.create(
81
  model="claude-3-opus-20240229",
@@ -87,38 +123,32 @@ def generate_test(subject):
87
  }]
88
  )
89
 
90
- # Extract usage information
91
- input_tokens = message.usage.input_tokens
92
- output_tokens = message.usage.output_tokens
93
- input_cost = (input_tokens / 1000) * 0.015
94
- output_cost = (output_tokens / 1000) * 0.075
95
- total_cost = input_cost + output_cost
96
-
97
- usage_stats = f"""
98
- \n---\nUsage Statistics:
99
- • Input Tokens: {input_tokens:,}
100
- • Output Tokens: {output_tokens:,}
101
- • Total Tokens: {input_tokens + output_tokens:,}
102
-
103
- Cost Breakdown:
104
- • Input Cost: ${input_cost:.4f}
105
- • Output Cost: ${output_cost:.4f}
106
- • Total Cost: ${total_cost:.4f}
107
- """
108
-
109
  if hasattr(message, 'content') and len(message.content) > 0:
110
  response_text = message.content[0].text
111
- formatted_response = clean_latex(response_text) + usage_stats
112
- return formatted_response
113
  else:
114
  return "Error: No content in response"
115
 
116
- except ValueError as e:
117
- return f"Configuration Error: {str(e)}"
118
  except Exception as e:
119
  return f"Error: {str(e)}"
120
 
121
- # Subject choices remain the same
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  subjects = [
123
  "Single Variable Calculus",
124
  "Multivariable Calculus",
@@ -132,27 +162,73 @@ subjects = [
132
  "Topology"
133
  ]
134
 
 
 
 
 
135
  # Create Gradio interface
136
- interface = gr.Interface(
137
- fn=generate_test,
138
- inputs=gr.Dropdown(
139
- choices=subjects,
140
- label="Select Mathematics Subject",
141
- info="Choose a subject for the exam questions"
142
- ),
143
- outputs=gr.Markdown(
 
 
 
 
 
 
144
  label="Generated Test",
145
  latex_delimiters=[
146
  {"left": "$$", "right": "$$", "display": True},
147
  {"left": "$", "right": "$", "display": False}
148
  ]
149
- ),
150
- title="Advanced Mathematics Test Generator",
151
- description="""Generates unique university-level mathematics exam questions with solutions using Claude 3 Opus.
152
- Each test features different topics and difficulty levels. Limited to 25 requests per day.""",
153
- theme="default",
154
- allow_flagging="never"
155
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
156
 
157
  if __name__ == "__main__":
158
  interface.launch()
 
4
  from datetime import datetime, timedelta
5
  from collections import deque
6
  import random
7
+ import tempfile
8
+ import subprocess
9
+ from pathlib import Path
10
 
11
  # Initialize Anthropic client
12
  anthropic = Anthropic(
 
34
  text = text.replace('\n', '\n\n')
35
  return text
36
 
37
+ def create_latex_document(content, questions_only=False):
38
+ """Create a complete LaTeX document"""
39
+ latex_header = r"""\documentclass{article}
40
+ \usepackage{amsmath,amssymb}
41
+ \usepackage[margin=1in]{geometry}
42
+ \begin{document}
43
+ """
44
+ latex_footer = r"\end{document}"
45
+
46
+ if questions_only:
47
+ # Extract only the questions (everything before "Solution:")
48
+ questions = []
49
+ for question in content.split('\n'):
50
+ if 'Solution:' in question:
51
+ continue
52
+ questions.append(question)
53
+ content = '\n'.join(questions)
54
+
55
+ return f"{latex_header}\n{content}\n{latex_footer}"
56
+
57
+ def latex_to_pdf(latex_content):
58
+ """Convert LaTeX content to PDF"""
59
+ with tempfile.TemporaryDirectory() as tmpdir:
60
+ tex_path = Path(tmpdir) / "output.tex"
61
+ with open(tex_path, "w", encoding="utf-8") as f:
62
+ f.write(latex_content)
63
+
64
+ # Run pdflatex twice to resolve references
65
+ subprocess.run(["pdflatex", "-interaction=nonstopmode", str(tex_path)],
66
+ cwd=tmpdir, capture_output=True)
67
+ subprocess.run(["pdflatex", "-interaction=nonstopmode", str(tex_path)],
68
+ cwd=tmpdir, capture_output=True)
69
+
70
+ pdf_path = Path(tmpdir) / "output.pdf"
71
+ if pdf_path.exists():
72
+ return pdf_path.read_bytes()
73
+ return None
74
+
75
+ def generate_test_with_format(subject, output_format):
76
+ """Generate a math test with specified output format"""
77
  try:
78
  check_api_key()
79
  if not check_rate_limit():
 
81
 
82
  request_history.append(datetime.now())
83
 
 
84
  topics = {
85
  "Single Variable Calculus": ["limits", "derivatives", "integrals", "series", "applications"],
86
+ "Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization"],
87
+ "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
88
  # ... add topics for other subjects
89
  }
90
 
 
98
  system_prompt = f"""You will write math exam questions. Follow these requirements EXACTLY:
99
  1. Write exactly 3 university-level questions focusing on these specific topics: {', '.join(selected_topics)}
100
  2. Make the questions {difficulty_distribution}
101
+ 3. ALL questions must be computational or proof-based problems. NO conceptual or explanation questions.
102
+ 4. Each question must require mathematical work, calculations, or formal proofs
103
  5. For LaTeX math formatting:
104
  - Use $ for simple inline math
105
  - For equations and solution steps, use $$ on separate lines
 
109
  7. Include detailed solutions after each question
110
  8. Keep formatting simple and clear
111
 
112
+ Important: Every question must require mathematical computation or proof. Do not ask for explanations, descriptions, or concepts."""
 
113
 
114
+ temperature = 0.7
 
 
 
115
 
116
  message = anthropic.messages.create(
117
  model="claude-3-opus-20240229",
 
123
  }]
124
  )
125
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  if hasattr(message, 'content') and len(message.content) > 0:
127
  response_text = message.content[0].text
128
+ return clean_latex(response_text)
 
129
  else:
130
  return "Error: No content in response"
131
 
 
 
132
  except Exception as e:
133
  return f"Error: {str(e)}"
134
 
135
+ def create_download_files(test_content):
136
+ """Create downloadable files in different formats"""
137
+ # Full test (questions and solutions)
138
+ full_latex = create_latex_document(test_content, questions_only=False)
139
+ full_pdf = latex_to_pdf(full_latex)
140
+
141
+ # Questions only
142
+ questions_latex = create_latex_document(test_content, questions_only=True)
143
+ questions_pdf = latex_to_pdf(questions_latex)
144
+
145
+ return {
146
+ "full_latex": full_latex,
147
+ "full_pdf": full_pdf,
148
+ "questions_latex": questions_latex,
149
+ "questions_pdf": questions_pdf
150
+ }
151
+
152
  subjects = [
153
  "Single Variable Calculus",
154
  "Multivariable Calculus",
 
162
  "Topology"
163
  ]
164
 
165
+ def download_handler(file_content, filename):
166
+ """Handle file downloads"""
167
+ return file_content
168
+
169
  # Create Gradio interface
170
+ with gr.Blocks() as interface:
171
+ gr.Markdown("# Advanced Mathematics Test Generator")
172
+ gr.Markdown("""Generates unique university-level mathematics exam questions with solutions using Claude 3 Opus.
173
+ Each test features different topics and difficulty levels. Limited to 25 requests per day.""")
174
+
175
+ with gr.Row():
176
+ subject_dropdown = gr.Dropdown(
177
+ choices=subjects,
178
+ label="Select Mathematics Subject",
179
+ info="Choose a subject for the exam questions"
180
+ )
181
+ generate_btn = gr.Button("Generate Test")
182
+
183
+ output_text = gr.Markdown(
184
  label="Generated Test",
185
  latex_delimiters=[
186
  {"left": "$$", "right": "$$", "display": True},
187
  {"left": "$", "right": "$", "display": False}
188
  ]
189
+ )
190
+
191
+ with gr.Row():
192
+ with gr.Column():
193
+ gr.Markdown("### Download Questions Only")
194
+ questions_latex_btn = gr.Button("Download Questions (LaTeX)")
195
+ questions_pdf_btn = gr.Button("Download Questions (PDF)")
196
+
197
+ with gr.Column():
198
+ gr.Markdown("### Download Full Test with Solutions")
199
+ full_latex_btn = gr.Button("Download Full Test (LaTeX)")
200
+ full_pdf_btn = gr.Button("Download Full Test (PDF)")
201
+
202
+ # Hidden components for downloads
203
+ questions_latex_output = gr.File(label="Questions LaTeX", visible=False)
204
+ questions_pdf_output = gr.File(label="Questions PDF", visible=False)
205
+ full_latex_output = gr.File(label="Full LaTeX", visible=False)
206
+ full_pdf_output = gr.File(label="Full PDF", visible=False)
207
+
208
+ # Event handlers
209
+ def generate_and_prepare_downloads(subject):
210
+ test_content = generate_test_with_format(subject, "latex")
211
+ files = create_download_files(test_content)
212
+ return (
213
+ test_content,
214
+ (files["questions_latex"], "questions.tex"),
215
+ (files["questions_pdf"], "questions.pdf"),
216
+ (files["full_latex"], "full_test.tex"),
217
+ (files["full_pdf"], "full_test.pdf")
218
+ )
219
+
220
+ generate_btn.click(
221
+ generate_and_prepare_downloads,
222
+ inputs=[subject_dropdown],
223
+ outputs=[output_text, questions_latex_output, questions_pdf_output,
224
+ full_latex_output, full_pdf_output]
225
+ )
226
+
227
+ # Download button clicks
228
+ questions_latex_btn.click(lambda: questions_latex_output.value)
229
+ questions_pdf_btn.click(lambda: questions_pdf_output.value)
230
+ full_latex_btn.click(lambda: full_latex_output.value)
231
+ full_pdf_btn.click(lambda: full_pdf_output.value)
232
 
233
  if __name__ == "__main__":
234
  interface.launch()