joshuarauh commited on
Commit
6439bc9
·
verified ·
1 Parent(s): 8f5670f

add error logging

Browse files
Files changed (1) hide show
  1. app.py +101 -91
app.py CHANGED
@@ -4,6 +4,12 @@ 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(
@@ -14,94 +20,84 @@ anthropic = Anthropic(
14
  MAX_REQUESTS_PER_DAY = 25
15
  request_history = deque(maxlen=1000)
16
 
17
- def check_api_key():
18
- """Verify API key is configured"""
19
- if not os.environ.get('ANTHROPIC_API_KEY'):
20
- raise ValueError("Anthropic API key not found. Please configure it in HuggingFace Spaces settings.")
21
-
22
- def check_rate_limit():
23
- """Check if we're within rate limits"""
24
- now = datetime.now()
25
- while request_history and (now - request_history[0]) > timedelta(days=1):
26
- request_history.popleft()
27
- return len(request_history) < MAX_REQUESTS_PER_DAY
28
-
29
- def clean_latex(text):
30
- """Simple LaTeX cleaning"""
31
- text = text.replace('\n', '\n\n')
32
- return text
33
-
34
  def create_latex_document(content, questions_only=False):
35
  """Create a complete LaTeX document"""
36
- latex_header = r"""\documentclass{article}
 
37
  \usepackage{amsmath,amssymb}
38
  \usepackage[margin=1in]{geometry}
39
  \begin{document}
40
  \title{Mathematics Test}
41
  \maketitle
42
  """
43
- latex_footer = r"\end{document}"
44
-
45
- if questions_only:
46
- # Extract only the questions (everything before "Solution:")
47
- processed_content = []
48
- current_question = []
49
- for line in content.split('\n'):
50
- if 'Solution:' in line:
51
- processed_content.append('\n'.join(current_question))
52
- current_question = []
53
- continue
54
- if any(line.startswith(f"{i})") for i in range(1, 4)):
55
- if current_question:
56
  processed_content.append('\n'.join(current_question))
57
- current_question = [line]
58
- elif current_question:
59
- current_question.append(line)
60
- if current_question:
61
- processed_content.append('\n'.join(current_question))
62
- content = '\n\n'.join(processed_content)
63
-
64
- return f"{latex_header}\n{content}\n{latex_footer}"
 
 
 
 
 
 
 
 
 
 
65
 
66
  def generate_test(subject):
67
  """Generate a math test"""
68
  try:
69
- check_api_key()
70
- if not check_rate_limit():
 
 
 
 
 
 
 
 
 
71
  return "Daily request limit reached. Please try again tomorrow.", None, None
72
 
73
- request_history.append(datetime.now())
74
 
75
  topics = {
76
  "Single Variable Calculus": ["limits", "derivatives", "integrals", "series", "applications"],
77
  "Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization"],
78
  "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
79
- # ... add topics for other subjects
80
  }
81
 
82
  selected_topics = random.sample(topics.get(subject, ["general"]), min(3, len(topics.get(subject, ["general"]))))
83
- difficulty_distribution = random.choice([
84
- "one easy, one medium, one challenging",
85
- "two medium, one very challenging",
86
- "one medium, two challenging"
87
- ])
88
 
89
  system_prompt = f"""You will write math exam questions. Follow these requirements EXACTLY:
90
  1. Write exactly 3 university-level questions focusing on these specific topics: {', '.join(selected_topics)}
91
- 2. Make the questions {difficulty_distribution}
92
- 3. ALL questions must be computational or proof-based problems. NO conceptual or explanation questions.
93
- 4. Each question must require mathematical work, calculations, or formal proofs
94
- 5. For LaTeX math formatting:
95
  - Use $ for simple inline math
96
  - For equations and solution steps, use $$ on separate lines
97
  - For multi-step solutions, put each step on its own line in $$ $$
98
  - DO NOT use \\begin{{aligned}} or any other environments
99
- 6. Number each question as 1), 2), 3)
100
- 7. Include detailed solutions after each question
101
- 8. Keep formatting simple and clear
102
-
103
- Important: Every question must require mathematical computation or proof. Do not ask for explanations, descriptions, or concepts."""
104
 
 
105
  message = anthropic.messages.create(
106
  model="claude-3-opus-20240229",
107
  max_tokens=1500,
@@ -112,34 +108,36 @@ def generate_test(subject):
112
  }]
113
  )
114
 
115
- if hasattr(message, 'content') and len(message.content) > 0:
116
- response_text = message.content[0].text
117
- cleaned_text = clean_latex(response_text)
 
 
 
 
 
 
 
 
 
118
 
119
- # Create both versions of the LaTeX document
120
- full_latex = create_latex_document(cleaned_text, questions_only=False)
121
- questions_latex = create_latex_document(cleaned_text, questions_only=True)
 
122
 
123
- return cleaned_text, questions_latex, full_latex
124
- else:
125
- return "Error: No content in response", None, None
 
 
 
 
126
 
127
  except Exception as e:
 
128
  return f"Error: {str(e)}", None, None
129
 
130
- subjects = [
131
- "Single Variable Calculus",
132
- "Multivariable Calculus",
133
- "Linear Algebra",
134
- "Differential Equations",
135
- "Real Analysis",
136
- "Complex Analysis",
137
- "Abstract Algebra",
138
- "Probability Theory",
139
- "Numerical Analysis",
140
- "Topology"
141
- ]
142
-
143
  # Create Gradio interface
144
  with gr.Blocks() as interface:
145
  gr.Markdown("# Advanced Mathematics Test Generator")
@@ -148,14 +146,25 @@ with gr.Blocks() as interface:
148
 
149
  with gr.Row():
150
  subject_dropdown = gr.Dropdown(
151
- choices=subjects,
 
 
 
 
 
 
 
 
 
 
 
152
  label="Select Mathematics Subject",
153
  info="Choose a subject for the exam questions"
154
  )
155
  generate_btn = gr.Button("Generate Test")
156
 
157
  output_text = gr.Markdown(
158
- label="Generated Test",
159
  latex_delimiters=[
160
  {"left": "$$", "right": "$$", "display": True},
161
  {"left": "$", "right": "$", "display": False}
@@ -163,19 +172,19 @@ with gr.Blocks() as interface:
163
  )
164
 
165
  with gr.Row():
166
- with gr.Column():
167
- gr.Markdown("### Download LaTeX Files")
168
- questions_file = gr.File(label="Questions Only (LaTeX)")
169
- full_file = gr.File(label="Full Test with Solutions (LaTeX)")
170
 
171
  def generate_and_prepare_files(subject):
172
- preview, questions_latex, full_latex = generate_test(subject)
 
173
 
174
- # Create temporary files for download
175
- questions_file = {"content": questions_latex.encode(), "name": "questions.tex"}
176
- full_file = {"content": full_latex.encode(), "name": "full_test.tex"}
177
-
178
- return preview, questions_file, full_file
 
179
 
180
  generate_btn.click(
181
  generate_and_prepare_files,
@@ -184,4 +193,5 @@ with gr.Blocks() as interface:
184
  )
185
 
186
  if __name__ == "__main__":
 
187
  interface.launch()
 
4
  from datetime import datetime, timedelta
5
  from collections import deque
6
  import random
7
+ import logging
8
+ import tempfile
9
+
10
+ # Set up logging
11
+ logging.basicConfig(level=logging.DEBUG)
12
+ logger = logging.getLogger(__name__)
13
 
14
  # Initialize Anthropic client
15
  anthropic = Anthropic(
 
20
  MAX_REQUESTS_PER_DAY = 25
21
  request_history = deque(maxlen=1000)
22
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
23
  def create_latex_document(content, questions_only=False):
24
  """Create a complete LaTeX document"""
25
+ try:
26
+ latex_header = r"""\documentclass{article}
27
  \usepackage{amsmath,amssymb}
28
  \usepackage[margin=1in]{geometry}
29
  \begin{document}
30
  \title{Mathematics Test}
31
  \maketitle
32
  """
33
+ latex_footer = r"\end{document}"
34
+
35
+ if questions_only:
36
+ processed_content = []
37
+ current_question = []
38
+ for line in content.split('\n'):
39
+ if 'Solution:' in line:
 
 
 
 
 
 
40
  processed_content.append('\n'.join(current_question))
41
+ current_question = []
42
+ continue
43
+ if any(line.startswith(f"{i})") for i in range(1, 4)):
44
+ if current_question:
45
+ processed_content.append('\n'.join(current_question))
46
+ current_question = [line]
47
+ elif current_question:
48
+ current_question.append(line)
49
+ if current_question:
50
+ processed_content.append('\n'.join(current_question))
51
+ content = '\n\n'.join(processed_content)
52
+
53
+ full_document = f"{latex_header}\n{content}\n{latex_footer}"
54
+ logger.debug(f"Created {'questions-only' if questions_only else 'full'} LaTeX document")
55
+ return full_document
56
+ except Exception as e:
57
+ logger.error(f"Error creating LaTeX document: {str(e)}")
58
+ raise
59
 
60
  def generate_test(subject):
61
  """Generate a math test"""
62
  try:
63
+ if not os.environ.get('ANTHROPIC_API_KEY'):
64
+ logger.error("Anthropic API key not found")
65
+ return "Error: Anthropic API key not configured", None, None
66
+
67
+ logger.debug(f"Generating test for subject: {subject}")
68
+
69
+ # Check rate limit
70
+ now = datetime.now()
71
+ while request_history and (now - request_history[0]) > timedelta(days=1):
72
+ request_history.popleft()
73
+ if len(request_history) >= MAX_REQUESTS_PER_DAY:
74
  return "Daily request limit reached. Please try again tomorrow.", None, None
75
 
76
+ request_history.append(now)
77
 
78
  topics = {
79
  "Single Variable Calculus": ["limits", "derivatives", "integrals", "series", "applications"],
80
  "Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization"],
81
  "Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
 
82
  }
83
 
84
  selected_topics = random.sample(topics.get(subject, ["general"]), min(3, len(topics.get(subject, ["general"]))))
85
+ logger.debug(f"Selected topics: {selected_topics}")
 
 
 
 
86
 
87
  system_prompt = f"""You will write math exam questions. Follow these requirements EXACTLY:
88
  1. Write exactly 3 university-level questions focusing on these specific topics: {', '.join(selected_topics)}
89
+ 2. ALL questions must be computational or proof-based problems. NO conceptual or explanation questions.
90
+ 3. Each question must require mathematical work, calculations, or formal proofs
91
+ 4. For LaTeX math formatting:
 
92
  - Use $ for simple inline math
93
  - For equations and solution steps, use $$ on separate lines
94
  - For multi-step solutions, put each step on its own line in $$ $$
95
  - DO NOT use \\begin{{aligned}} or any other environments
96
+ 5. Number each question as 1), 2), 3)
97
+ 6. Include detailed solutions after each question
98
+ 7. Keep formatting simple and clear"""
 
 
99
 
100
+ logger.debug("Sending request to Anthropic API")
101
  message = anthropic.messages.create(
102
  model="claude-3-opus-20240229",
103
  max_tokens=1500,
 
108
  }]
109
  )
110
 
111
+ if not hasattr(message, 'content') or not message.content:
112
+ logger.error("No content received from Anthropic API")
113
+ return "Error: No content received from API", None, None
114
+
115
+ response_text = message.content[0].text
116
+ logger.debug("Successfully received response from Anthropic API")
117
+
118
+ # Create temporary files
119
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.tex', delete=False) as f_questions:
120
+ questions_latex = create_latex_document(response_text, questions_only=True)
121
+ f_questions.write(questions_latex)
122
+ questions_path = f_questions.name
123
 
124
+ with tempfile.NamedTemporaryFile(mode='w', suffix='.tex', delete=False) as f_full:
125
+ full_latex = create_latex_document(response_text, questions_only=False)
126
+ f_full.write(full_latex)
127
+ full_path = f_full.name
128
 
129
+ logger.debug("Successfully created temporary files")
130
+
131
+ return (
132
+ response_text,
133
+ (questions_path, "questions.tex"),
134
+ (full_path, "full_test.tex")
135
+ )
136
 
137
  except Exception as e:
138
+ logger.error(f"Error generating test: {str(e)}")
139
  return f"Error: {str(e)}", None, None
140
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  # Create Gradio interface
142
  with gr.Blocks() as interface:
143
  gr.Markdown("# Advanced Mathematics Test Generator")
 
146
 
147
  with gr.Row():
148
  subject_dropdown = gr.Dropdown(
149
+ choices=[
150
+ "Single Variable Calculus",
151
+ "Multivariable Calculus",
152
+ "Linear Algebra",
153
+ "Differential Equations",
154
+ "Real Analysis",
155
+ "Complex Analysis",
156
+ "Abstract Algebra",
157
+ "Probability Theory",
158
+ "Numerical Analysis",
159
+ "Topology"
160
+ ],
161
  label="Select Mathematics Subject",
162
  info="Choose a subject for the exam questions"
163
  )
164
  generate_btn = gr.Button("Generate Test")
165
 
166
  output_text = gr.Markdown(
167
+ label="Generated Test Preview",
168
  latex_delimiters=[
169
  {"left": "$$", "right": "$$", "display": True},
170
  {"left": "$", "right": "$", "display": False}
 
172
  )
173
 
174
  with gr.Row():
175
+ questions_file = gr.File(label="Questions Only (LaTeX)")
176
+ full_file = gr.File(label="Full Test with Solutions (LaTeX)")
 
 
177
 
178
  def generate_and_prepare_files(subject):
179
+ logger.debug("Starting test generation")
180
+ preview, questions_path, full_path = generate_test(subject)
181
 
182
+ if questions_path and full_path:
183
+ logger.debug("Test generation successful, preparing files")
184
+ return preview, questions_path, full_path
185
+ else:
186
+ logger.error("Test generation failed")
187
+ return preview, None, None
188
 
189
  generate_btn.click(
190
  generate_and_prepare_files,
 
193
  )
194
 
195
  if __name__ == "__main__":
196
+ logger.info("Starting application")
197
  interface.launch()