Spaces:
Running
Running
Update app.py
Browse files
app.py
CHANGED
@@ -35,6 +35,90 @@ if openai.api_key is None:
|
|
35 |
MAX_REQUESTS_PER_DAY = 500
|
36 |
request_history = deque(maxlen=1000)
|
37 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
38 |
SYMPY_GUIDELINES = """
|
39 |
When writing SymPy code to verify solutions:
|
40 |
|
@@ -459,17 +543,36 @@ def create_latex_document(content, questions_only=False):
|
|
459 |
latex_footer = r"\end{document}"
|
460 |
|
461 |
if questions_only:
|
462 |
-
#
|
463 |
-
|
464 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
465 |
|
466 |
full_document = f"{latex_header}\n{content}\n{latex_footer}"
|
467 |
logger.debug(f"Created {'questions-only' if questions_only else 'full'} LaTeX document")
|
468 |
return full_document
|
|
|
469 |
except Exception as e:
|
470 |
logger.error(f"Error creating LaTeX document: {str(e)}")
|
471 |
raise
|
472 |
-
|
473 |
def save_to_temp_file(content, filename):
|
474 |
"""Save content to a temporary file and return the path"""
|
475 |
try:
|
@@ -701,7 +804,7 @@ def append_chatgpt_verification(initial_response, SYMPY_CONFIRMED, final_verific
|
|
701 |
logger.error(f"Error in verification process: {str(e)}")
|
702 |
return initial_response + f"\n\nError in ChatGPT verification: {str(e)}"
|
703 |
|
704 |
-
def generate_question(subject, difficulty, question_type, use_enhancement=False, include_chatgpt="no"):
|
705 |
"""Generate a single math question with additional verification"""
|
706 |
try:
|
707 |
logger.debug(f"ChatGPT verification: {'enabled' if include_chatgpt == 'yes' else 'disabled'}")
|
@@ -721,23 +824,8 @@ def generate_question(subject, difficulty, question_type, use_enhancement=False,
|
|
721 |
|
722 |
request_history.append(now)
|
723 |
|
724 |
-
|
725 |
-
|
726 |
-
"linear_approximation", "lhopitals rule", "integration techniques","improper integrals","area between curves",
|
727 |
-
"volumes of revolution","arc length","parametric equations","polar coordinates"],
|
728 |
-
"Multivariable Calculus": ["partial derivatives", "multiple integrals", "vector fields", "optimization"],
|
729 |
-
"Linear Algebra": ["matrices", "vector spaces", "eigenvalues", "linear transformations"],
|
730 |
-
"Differential Equations": ["first order equations", "second order equations", "systems", "stability analysis"],
|
731 |
-
"Real Analysis": ["sequences", "series", "continuity", "differentiation", "integration"],
|
732 |
-
"Complex Analysis": ["complex functions", "analyticity", "contour integration", "residues"],
|
733 |
-
"Abstract Algebra": ["groups", "rings", "fields", "homomorphisms"],
|
734 |
-
"Probability Theory": ["probability spaces", "random variables", "distributions", "limit theorems"],
|
735 |
-
"Numerical Analysis": ["approximation", "interpolation", "numerical integration", "error analysis"],
|
736 |
-
"Topology": ["metric spaces", "continuity", "compactness", "connectedness"]
|
737 |
-
}
|
738 |
-
|
739 |
-
selected_topic = random.choice(topics.get(subject, ["general"]))
|
740 |
-
logger.debug(f"Selected topic: {selected_topic}")
|
741 |
|
742 |
difficulty_params = get_difficulty_parameters(difficulty)
|
743 |
problem_type_addition = get_problem_type_addition(question_type)
|
@@ -1215,7 +1303,19 @@ Remember to write out the complete solution even if you are repeating things fro
|
|
1215 |
except Exception as e:
|
1216 |
logger.error(f"Error in final verification: {str(e)}")
|
1217 |
return f"Error in final verification: {str(e)}"
|
1218 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1219 |
# Create Gradio interface
|
1220 |
with gr.Blocks() as interface:
|
1221 |
gr.Markdown("# Advanced Mathematics Question Generator")
|
@@ -1240,7 +1340,22 @@ with gr.Blocks() as interface:
|
|
1240 |
label="Select Mathematics Subject",
|
1241 |
info="Choose a subject for the question"
|
1242 |
)
|
1243 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1244 |
difficulty_slider = gr.Slider(
|
1245 |
minimum=1,
|
1246 |
maximum=5,
|
@@ -1295,12 +1410,13 @@ with gr.Blocks() as interface:
|
|
1295 |
subject_dropdown,
|
1296 |
difficulty_slider,
|
1297 |
question_type,
|
|
|
1298 |
use_enhancement,
|
1299 |
chatgpt_verify
|
1300 |
],
|
1301 |
-
|
1302 |
)
|
1303 |
-
|
1304 |
if __name__ == "__main__":
|
1305 |
logger.info("Starting application")
|
1306 |
interface.launch()
|
|
|
35 |
MAX_REQUESTS_PER_DAY = 500
|
36 |
request_history = deque(maxlen=1000)
|
37 |
|
38 |
+
# Define subtopic mappings
|
39 |
+
SUBJECT_SUBTOPICS = {
|
40 |
+
"Single Variable Calculus": [
|
41 |
+
"limits",
|
42 |
+
"derivatives",
|
43 |
+
"integrals",
|
44 |
+
"related rates",
|
45 |
+
"linear approximation",
|
46 |
+
"integration techniques",
|
47 |
+
"improper integrals",
|
48 |
+
"area between curves",
|
49 |
+
"volumes of revolution",
|
50 |
+
"arc length",
|
51 |
+
"parametric equations",
|
52 |
+
"polar coordinates",
|
53 |
+
"sequences",
|
54 |
+
"series",
|
55 |
+
"Taylor series",
|
56 |
+
"L'H么pital's rule",
|
57 |
+
"mean value theorem",
|
58 |
+
"fundamental theorem of calculus"
|
59 |
+
],
|
60 |
+
"Multivariable Calculus": [
|
61 |
+
"partial derivatives",
|
62 |
+
"multiple integrals",
|
63 |
+
"vector fields",
|
64 |
+
"optimization",
|
65 |
+
"stokes theorem",
|
66 |
+
"green's theorem",
|
67 |
+
"line intergals",
|
68 |
+
"parametric equations",
|
69 |
+
"spherical coordinates"
|
70 |
+
],
|
71 |
+
"Linear Algebra": [
|
72 |
+
"matrices",
|
73 |
+
"vector spaces",
|
74 |
+
"eigenvalues",
|
75 |
+
"linear transformations"
|
76 |
+
],
|
77 |
+
"Differential Equations": [
|
78 |
+
"first order equations",
|
79 |
+
"second order equations",
|
80 |
+
"systems",
|
81 |
+
"stability analysis"
|
82 |
+
],
|
83 |
+
"Real Analysis": [
|
84 |
+
"sequences",
|
85 |
+
"series",
|
86 |
+
"continuity",
|
87 |
+
"differentiation",
|
88 |
+
"integration"
|
89 |
+
],
|
90 |
+
"Complex Analysis": [
|
91 |
+
"complex functions",
|
92 |
+
"analyticity",
|
93 |
+
"contour integration",
|
94 |
+
"residues"
|
95 |
+
],
|
96 |
+
"Abstract Algebra": [
|
97 |
+
"groups",
|
98 |
+
"rings",
|
99 |
+
"fields",
|
100 |
+
"homomorphisms"
|
101 |
+
],
|
102 |
+
"Probability Theory": [
|
103 |
+
"probability spaces",
|
104 |
+
"random variables",
|
105 |
+
"distributions",
|
106 |
+
"limit theorems"
|
107 |
+
],
|
108 |
+
"Numerical Analysis": [
|
109 |
+
"approximation",
|
110 |
+
"interpolation",
|
111 |
+
"numerical integration",
|
112 |
+
"error analysis"
|
113 |
+
],
|
114 |
+
"Topology": [
|
115 |
+
"metric spaces",
|
116 |
+
"continuity",
|
117 |
+
"compactness",
|
118 |
+
"connectedness"
|
119 |
+
],
|
120 |
+
}
|
121 |
+
|
122 |
SYMPY_GUIDELINES = """
|
123 |
When writing SymPy code to verify solutions:
|
124 |
|
|
|
543 |
latex_footer = r"\end{document}"
|
544 |
|
545 |
if questions_only:
|
546 |
+
# Find where the question ends and solution begins
|
547 |
+
question_marker = "Here is a test question"
|
548 |
+
solution_marker = "Here is a detailed solution"
|
549 |
+
|
550 |
+
q_start = content.find(question_marker)
|
551 |
+
s_start = content.find(solution_marker)
|
552 |
+
|
553 |
+
if q_start != -1 and s_start != -1:
|
554 |
+
# Extract only the question part
|
555 |
+
question_content = content[q_start:s_start].strip()
|
556 |
+
|
557 |
+
# Remove any SymPy code or verification text if present
|
558 |
+
code_start = question_content.find('```python')
|
559 |
+
if code_start != -1:
|
560 |
+
question_content = question_content[:code_start].strip()
|
561 |
+
|
562 |
+
content = question_content
|
563 |
+
else:
|
564 |
+
# Fallback: try to split at the first occurrence of "Solution:"
|
565 |
+
parts = content.split('Solution:', 1)
|
566 |
+
content = parts[0].strip()
|
567 |
|
568 |
full_document = f"{latex_header}\n{content}\n{latex_footer}"
|
569 |
logger.debug(f"Created {'questions-only' if questions_only else 'full'} LaTeX document")
|
570 |
return full_document
|
571 |
+
|
572 |
except Exception as e:
|
573 |
logger.error(f"Error creating LaTeX document: {str(e)}")
|
574 |
raise
|
575 |
+
|
576 |
def save_to_temp_file(content, filename):
|
577 |
"""Save content to a temporary file and return the path"""
|
578 |
try:
|
|
|
804 |
logger.error(f"Error in verification process: {str(e)}")
|
805 |
return initial_response + f"\n\nError in ChatGPT verification: {str(e)}"
|
806 |
|
807 |
+
def generate_question(subject, difficulty, question_type, subtopic, use_enhancement=False, include_chatgpt="no"):
|
808 |
"""Generate a single math question with additional verification"""
|
809 |
try:
|
810 |
logger.debug(f"ChatGPT verification: {'enabled' if include_chatgpt == 'yes' else 'disabled'}")
|
|
|
824 |
|
825 |
request_history.append(now)
|
826 |
|
827 |
+
selected_topic = subtopic
|
828 |
+
logger.debug(f"Using selected subtopic: {selected_topic}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
829 |
|
830 |
difficulty_params = get_difficulty_parameters(difficulty)
|
831 |
problem_type_addition = get_problem_type_addition(question_type)
|
|
|
1303 |
except Exception as e:
|
1304 |
logger.error(f"Error in final verification: {str(e)}")
|
1305 |
return f"Error in final verification: {str(e)}"
|
1306 |
+
|
1307 |
+
# Add this function to update subtopic choices
|
1308 |
+
def update_subtopics(subject):
|
1309 |
+
if subject in SUBJECT_SUBTOPICS:
|
1310 |
+
return {
|
1311 |
+
"choices": SUBJECT_SUBTOPICS[subject],
|
1312 |
+
"visible": True
|
1313 |
+
}
|
1314 |
+
return {
|
1315 |
+
"choices": [],
|
1316 |
+
"visible": False
|
1317 |
+
}
|
1318 |
+
|
1319 |
# Create Gradio interface
|
1320 |
with gr.Blocks() as interface:
|
1321 |
gr.Markdown("# Advanced Mathematics Question Generator")
|
|
|
1340 |
label="Select Mathematics Subject",
|
1341 |
info="Choose a subject for the question"
|
1342 |
)
|
1343 |
+
|
1344 |
+
# Add this after subject_dropdown
|
1345 |
+
subtopic_dropdown = gr.Dropdown(
|
1346 |
+
choices=[], # Empty initially
|
1347 |
+
label="Select Subtopic",
|
1348 |
+
info="Choose a specific topic within the subject",
|
1349 |
+
visible=False # Hidden initially
|
1350 |
+
)
|
1351 |
+
|
1352 |
+
# Connect the update function
|
1353 |
+
subject_dropdown.change(
|
1354 |
+
update_subtopics,
|
1355 |
+
inputs=[subject_dropdown],
|
1356 |
+
outputs=[subtopic_dropdown]
|
1357 |
+
)
|
1358 |
+
|
1359 |
difficulty_slider = gr.Slider(
|
1360 |
minimum=1,
|
1361 |
maximum=5,
|
|
|
1410 |
subject_dropdown,
|
1411 |
difficulty_slider,
|
1412 |
question_type,
|
1413 |
+
subtopic_dropdown, # Add this
|
1414 |
use_enhancement,
|
1415 |
chatgpt_verify
|
1416 |
],
|
1417 |
+
outputs=[output_text, questions_file, full_file]
|
1418 |
)
|
1419 |
+
|
1420 |
if __name__ == "__main__":
|
1421 |
logger.info("Starting application")
|
1422 |
interface.launch()
|