shukdevdattaEX commited on
Commit
185cb6a
·
verified ·
1 Parent(s): 2af3ec8

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +216 -146
app.py CHANGED
@@ -13,17 +13,27 @@ import tempfile
13
  import weasyprint
14
  from pathlib import Path
15
 
16
- # Function to convert markdown to HTML with styling
17
  def markdown_to_html(markdown_text, problem_text="", include_problem=True):
18
- """Convert markdown to styled HTML"""
19
 
20
  # Convert markdown to HTML
21
  html_content = markdown.markdown(markdown_text, extensions=['tables', 'fenced_code'])
22
 
 
 
 
 
 
 
 
 
 
 
23
  # Get current timestamp
24
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
25
 
26
- # Create styled HTML document
27
  styled_html = f"""
28
  <!DOCTYPE html>
29
  <html lang="en">
@@ -31,152 +41,222 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
31
  <meta charset="UTF-8">
32
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
33
  <title>Math Solution - Advanced Math Tutor</title>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  <style>
35
  body {{
36
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
37
- line-height: 1.6;
38
  color: #333;
39
- max-width: 800px;
40
  margin: 0 auto;
41
  padding: 20px;
42
- background-color: #f9f9f9;
43
  }}
44
  .container {{
45
  background-color: white;
46
- padding: 40px;
47
- border-radius: 10px;
48
- box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
49
  }}
50
  .header {{
51
  text-align: center;
52
- border-bottom: 3px solid #4CAF50;
53
- padding-bottom: 20px;
54
- margin-bottom: 30px;
55
  }}
56
  .header h1 {{
57
  color: #2c3e50;
58
  margin: 0;
59
- font-size: 2.5em;
 
60
  }}
61
  .header .subtitle {{
62
  color: #7f8c8d;
63
  font-style: italic;
64
  margin-top: 10px;
 
65
  }}
66
  .problem-section {{
67
- background-color: #e8f5e8;
68
- padding: 20px;
69
- border-radius: 8px;
70
- margin-bottom: 30px;
71
- border-left: 5px solid #4CAF50;
 
72
  }}
73
  .problem-section h2 {{
74
  color: #2c3e50;
75
  margin-top: 0;
 
 
 
 
 
76
  }}
77
  .solution-content {{
78
- background-color: #f8f9fa;
79
- padding: 25px;
80
- border-radius: 8px;
81
- border-left: 5px solid #007bff;
 
82
  }}
83
  h1, h2, h3, h4, h5, h6 {{
84
  color: #2c3e50;
85
- margin-top: 25px;
86
  margin-bottom: 15px;
 
87
  }}
88
  h2 {{
89
- border-bottom: 2px solid #eee;
90
- padding-bottom: 10px;
 
 
 
 
 
 
 
 
 
91
  }}
92
  code {{
93
- background-color: #f1f1f1;
94
- padding: 2px 6px;
95
- border-radius: 3px;
96
- font-family: 'Courier New', monospace;
97
- color: #d63384;
 
98
  }}
99
  pre {{
100
- background-color: #f8f8f8;
101
- padding: 15px;
102
- border-radius: 5px;
103
  overflow-x: auto;
104
- border: 1px solid #ddd;
 
105
  }}
106
  pre code {{
107
  background-color: transparent;
108
  padding: 0;
109
- color: inherit;
110
  }}
111
  .math-expression {{
112
- background-color: #fff3cd;
113
- padding: 10px;
114
- border-radius: 5px;
115
- border: 1px solid #ffeaa7;
116
- margin: 10px 0;
117
- font-family: 'Times New Roman', serif;
118
- font-size: 1.1em;
119
  }}
120
  .step {{
121
- margin: 20px 0;
122
- padding: 15px;
123
  background-color: #ffffff;
124
  border-radius: 8px;
125
  border: 1px solid #dee2e6;
 
126
  }}
127
  .final-answer {{
128
  background-color: #d4edda;
129
- border: 2px solid #4CAF50;
130
- padding: 20px;
131
- border-radius: 8px;
132
- margin-top: 30px;
133
  text-align: center;
134
- font-weight: bold;
135
- font-size: 1.2em;
 
 
 
136
  }}
137
  .timestamp {{
138
  text-align: right;
139
  color: #6c757d;
140
- font-size: 0.9em;
141
- margin-top: 30px;
142
- padding-top: 20px;
143
- border-top: 1px solid #eee;
144
  }}
145
  ul, ol {{
146
- padding-left: 25px;
 
147
  }}
148
  li {{
149
- margin: 8px 0;
150
  }}
151
  table {{
152
  border-collapse: collapse;
153
  width: 100%;
154
- margin: 20px 0;
 
155
  }}
156
  th, td {{
157
- border: 1px solid #ddd;
158
- padding: 12px;
159
  text-align: left;
160
  }}
161
  th {{
162
  background-color: #f8f9fa;
163
- font-weight: bold;
 
 
 
 
164
  }}
165
  .print-button {{
166
  background-color: #007bff;
167
  color: white;
168
  border: none;
169
- padding: 10px 20px;
170
- border-radius: 5px;
171
  cursor: pointer;
172
  font-size: 16px;
173
  margin: 10px 5px;
174
  display: inline-block;
175
  text-decoration: none;
 
 
176
  }}
177
  .print-button:hover {{
178
  background-color: #0056b3;
179
  }}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  @media print {{
181
  body {{
182
  background-color: white;
@@ -184,6 +264,7 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
184
  .container {{
185
  box-shadow: none;
186
  border: none;
 
187
  }}
188
  .print-button {{
189
  display: none;
@@ -194,6 +275,15 @@ def markdown_to_html(markdown_text, problem_text="", include_problem=True):
194
  function printPage() {{
195
  window.print();
196
  }}
 
 
 
 
 
 
 
 
 
197
  </script>
198
  </head>
199
  <body>
@@ -242,7 +332,7 @@ def save_html_to_file(html_content, filename_prefix="math_solution"):
242
 
243
  return file_path
244
 
245
- # Function to convert HTML to PDF
246
  def html_to_pdf(html_content, filename_prefix="math_solution"):
247
  """Convert HTML content to PDF and return the file path"""
248
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
@@ -253,7 +343,10 @@ def html_to_pdf(html_content, filename_prefix="math_solution"):
253
  pdf_path = os.path.join(temp_dir, filename)
254
 
255
  try:
256
- # Convert HTML to PDF using WeasyPrint
 
 
 
257
  weasyprint.HTML(string=html_content).write_pdf(pdf_path)
258
  return pdf_path
259
  except Exception as e:
@@ -279,10 +372,18 @@ def generate_math_solution_openrouter(api_key, problem_text, history=None):
279
  """You are an expert math tutor who explains concepts clearly and thoroughly.
280
  Analyze the given math problem and provide a detailed step-by-step solution.
281
  For each step:
282
- 1. Show the mathematical operation
283
  2. Explain why this step is necessary
284
  3. Connect it to relevant mathematical concepts
285
 
 
 
 
 
 
 
 
 
286
  Format your response using markdown with clear section headers.
287
  Begin with an "Initial Analysis" section, follow with numbered steps,
288
  and conclude with a "Final Answer" section.
@@ -290,7 +391,6 @@ def generate_math_solution_openrouter(api_key, problem_text, history=None):
290
  Use proper markdown formatting including:
291
  - Headers (##, ###)
292
  - **Bold text** for important points
293
- - `Code blocks` for mathematical expressions
294
  - Lists and numbered steps
295
  - Tables if needed for comparisons or data"""},
296
  ]
@@ -299,7 +399,7 @@ def generate_math_solution_openrouter(api_key, problem_text, history=None):
299
  if history:
300
  for exchange in history:
301
  messages.append({"role": "user", "content": exchange[0]})
302
- if len(exchange) > 1 and exchange[1]: # Check if there's a response
303
  messages.append({"role": "assistant", "content": exchange[1]})
304
 
305
  # Add the current problem
@@ -307,7 +407,7 @@ def generate_math_solution_openrouter(api_key, problem_text, history=None):
307
 
308
  # Create the completion
309
  completion = client.chat.completions.create(
310
- model="meta-llama/llama-3.3-70b-instruct:free",
311
  messages=messages,
312
  extra_headers={
313
  "HTTP-Referer": "https://advancedmathtutor.edu",
@@ -355,10 +455,18 @@ def generate_math_solution_together(api_key, problem_text, image_path=None, hist
355
  "content": """You are an expert math tutor who explains concepts clearly and thoroughly.
356
  Analyze the given math problem and provide a detailed step-by-step solution.
357
  For each step:
358
- 1. Show the mathematical operation
359
  2. Explain why this step is necessary
360
  3. Connect it to relevant mathematical concepts
361
 
 
 
 
 
 
 
 
 
362
  Format your response using markdown with clear section headers.
363
  Begin with an "Initial Analysis" section, follow with numbered steps,
364
  and conclude with a "Final Answer" section.
@@ -366,7 +474,6 @@ def generate_math_solution_together(api_key, problem_text, image_path=None, hist
366
  Use proper markdown formatting including:
367
  - Headers (##, ###)
368
  - **Bold text** for important points
369
- - `Code blocks` for mathematical expressions
370
  - Lists and numbered steps
371
  - Tables if needed for comparisons or data"""
372
  }
@@ -376,7 +483,7 @@ def generate_math_solution_together(api_key, problem_text, image_path=None, hist
376
  if history:
377
  for exchange in history:
378
  messages.append({"role": "user", "content": exchange[0]})
379
- if len(exchange) > 1 and exchange[1]: # Check if there's a response
380
  messages.append({"role": "assistant", "content": exchange[1]})
381
 
382
  # Prepare the user message content
@@ -431,7 +538,7 @@ def generate_math_solution_together(api_key, problem_text, image_path=None, hist
431
  # Convert to PDF
432
  pdf_file_path = html_to_pdf(html_solution, "together_solution")
433
 
434
- # Update history - for simplicity, just store the text problem
435
  if history is None:
436
  history = []
437
  history.append((problem_display, markdown_solution))
@@ -460,9 +567,8 @@ def create_demo():
460
  gr.Markdown("# 📚 Advanced Math Tutor")
461
  gr.Markdown("""
462
  This application provides step-by-step solutions to math problems using advanced AI models.
463
- Solutions are generated in **HTML format** with download and print-to-PDF capabilities.
464
- Choose between OpenRouter's Meta: Llama 3.3 70B Instruct for text-based problems or Together AI's
465
- Apriel-1.5-15b-Thinker for problems with images.
466
  """)
467
 
468
  # Main tabs
@@ -486,7 +592,7 @@ def create_demo():
486
  ["Solve the quadratic equation: 3x² + 5x - 2 = 0"],
487
  ["Find the derivative of f(x) = x³ln(x)"],
488
  ["Calculate the area of a circle with radius 5 cm"],
489
- ["Find all values of x that satisfy the equation: log₂(x-1) + log₂(x+3) = 5"]
490
  ],
491
  inputs=[text_problem_input],
492
  label="Example Problems"
@@ -496,7 +602,7 @@ def create_demo():
496
  openrouter_clear_btn = gr.Button("Clear")
497
 
498
  with gr.Column(scale=2):
499
- openrouter_solution_output = gr.HTML(label="Solution (HTML Format)")
500
 
501
  with gr.Row():
502
  openrouter_html_download = gr.File(
@@ -508,16 +614,13 @@ def create_demo():
508
  visible=False
509
  )
510
 
511
- # Store conversation history (invisible to user)
512
  openrouter_conversation_history = gr.State(value=None)
513
 
514
- # Button actions
515
  def handle_openrouter_submit(api_key, problem_text, history):
516
  html_solution, html_file, pdf_file, updated_history = generate_math_solution_openrouter(
517
  api_key, problem_text, history
518
  )
519
 
520
- # Return outputs including file updates
521
  return (
522
  html_solution,
523
  updated_history,
@@ -566,7 +669,7 @@ def create_demo():
566
  )
567
  together_problem_input = gr.Textbox(
568
  label="Problem Description (Optional)",
569
- placeholder="Enter additional context for the image problem...",
570
  lines=3
571
  )
572
  together_image_input = gr.Image(
@@ -578,7 +681,7 @@ def create_demo():
578
  together_clear_btn = gr.Button("Clear")
579
 
580
  with gr.Column(scale=2):
581
- together_solution_output = gr.HTML(label="Solution (HTML Format)")
582
 
583
  with gr.Row():
584
  together_html_download = gr.File(
@@ -590,16 +693,13 @@ def create_demo():
590
  visible=False
591
  )
592
 
593
- # Store conversation history (invisible to user)
594
  together_conversation_history = gr.State(value=None)
595
 
596
- # Button actions
597
  def handle_together_submit(api_key, problem_text, image_path, history):
598
  html_solution, html_file, pdf_file, updated_history = generate_math_solution_together(
599
  api_key, problem_text, image_path, history
600
  )
601
 
602
- # Return outputs including file updates
603
  return (
604
  html_solution,
605
  updated_history,
@@ -642,79 +742,49 @@ def create_demo():
642
  gr.Markdown("""
643
  ## How to Use the Advanced Math Tutor
644
 
645
- ### New Features 🎉
646
- - **HTML-formatted solutions**: All responses are now generated in beautiful HTML format
647
- - **Download HTML**: Download the complete solution as an HTML file
648
- - **Download PDF**: Convert and download solutions as PDF files
649
- - **Print functionality**: Use the "Print to PDF" button in the HTML output to print directly
 
650
 
651
  ### Getting Started
652
 
653
- #### For Text-Based Problems (OpenRouter)
654
- 1. You'll need an API key from OpenRouter
655
- 2. Sign up at [OpenRouter](https://openrouter.ai/) to get your API key
656
- 3. Enter your API key in the designated field in the "Text Problem Solver" tab
657
 
658
- #### For Image-Based Problems (Together AI)
659
- 1. You'll need an API key from Together AI
660
- 2. Sign up at [Together AI](https://www.together.ai/) to get your API key
661
- 3. Enter your API key in the designated field in the "Image Problem Solver" tab
662
- 4. Upload an image of your math problem
663
- 5. Optionally add text to provide additional context
664
 
665
- ### Solving Math Problems
666
- - For text problems: Type or paste your math problem in the input field
667
- - For image problems: Upload a clear image of the math problem
668
- - Click "Solve Problem" to get a detailed step-by-step solution in HTML format
669
- - Use the download buttons to save HTML or PDF versions
670
- - Click "Print to PDF" within the solution to print directly from your browser
671
 
672
- ### HTML Output Features
673
- - **Professional styling**: Clean, readable format with proper typography
674
- - **Mathematical expressions**: Highlighted math expressions and code blocks
675
- - **Step-by-step sections**: Clearly organized solution steps
676
- - **Print-friendly**: Optimized for printing and PDF conversion
677
- - **Timestamps**: Each solution includes generation timestamp
678
 
679
- ### Tips for Best Results
680
- - Be specific in your problem description
681
- - Include all necessary information
682
- - For complex equations, use clear notation
683
- - For algebraic expressions, use ^ for exponents (e.g., x^2 for x²)
684
- - Use parentheses to group terms clearly
685
- - For images, ensure the math problem is clearly visible and well-lit
686
-
687
- ### Types of Problems You Can Solve
688
- - Algebra (equations, inequalities, systems of equations)
689
- - Calculus (derivatives, integrals, limits)
690
- - Trigonometry
691
- - Geometry
692
- - Statistics and Probability
693
- - Number Theory
694
- - And many more!
695
-
696
- ### Required Dependencies
697
- To run this application, you'll need to install:
698
- ```bash
699
- pip install gradio openai together pillow markdown weasyprint
700
- ```
701
  """)
702
 
703
- # Footer
704
  gr.Markdown("""
705
  ---
706
  ### About
707
- This enhanced application uses Microsoft's Phi-4-reasoning-plus model via OpenRouter for text-based problems
708
- and Llama-Vision-Free via Together AI for image-based problems.
709
-
710
- **New Features:**
711
- - HTML-formatted responses with professional styling
712
- - Download solutions as HTML files
713
- - Convert and download solutions as PDF files
714
- - Print-to-PDF functionality
715
- - Enhanced formatting with mathematical expressions highlighting
716
-
717
- Your API keys are required but not stored permanently.
718
  """)
719
 
720
  return demo
 
13
  import weasyprint
14
  from pathlib import Path
15
 
16
+ # Function to convert markdown to HTML with styling and MathJax
17
  def markdown_to_html(markdown_text, problem_text="", include_problem=True):
18
+ """Convert markdown to styled HTML with proper math rendering"""
19
 
20
  # Convert markdown to HTML
21
  html_content = markdown.markdown(markdown_text, extensions=['tables', 'fenced_code'])
22
 
23
+ # Replace LaTeX delimiters for MathJax
24
+ # Handle display math: \[ ... \] and $$ ... $$
25
+ html_content = re.sub(r'\\\[(.*?)\\\]', r'\\[\1\\]', html_content, flags=re.DOTALL)
26
+ html_content = re.sub(r'\$\$(.*?)\$\$', r'\\[\1\\]', html_content, flags=re.DOTALL)
27
+
28
+ # Handle inline math: \( ... \) and $ ... $
29
+ html_content = re.sub(r'\\\((.*?)\\\)', r'\\(\1\\)', html_content)
30
+ # Be careful with single $ as it might be regular dollar signs
31
+ html_content = re.sub(r'(?<!\$)\$(?!\$)([^\$]+?)(?<!\$)\$(?!\$)', r'\\(\1\\)', html_content)
32
+
33
  # Get current timestamp
34
  timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
35
 
36
+ # Create styled HTML document with MathJax
37
  styled_html = f"""
38
  <!DOCTYPE html>
39
  <html lang="en">
 
41
  <meta charset="UTF-8">
42
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
43
  <title>Math Solution - Advanced Math Tutor</title>
44
+
45
+ <!-- MathJax for rendering mathematical notation -->
46
+ <script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
47
+ <script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-mml-chtml.js"></script>
48
+ <script>
49
+ window.MathJax = {{
50
+ tex: {{
51
+ inlineMath: [['\\\\(', '\\\\)']],
52
+ displayMath: [['\\\\[', '\\\\]']],
53
+ processEscapes: true,
54
+ processEnvironments: true
55
+ }},
56
+ options: {{
57
+ skipHtmlTags: ['script', 'noscript', 'style', 'textarea', 'pre']
58
+ }}
59
+ }};
60
+ </script>
61
+
62
  <style>
63
  body {{
64
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
65
+ line-height: 1.8;
66
  color: #333;
67
+ max-width: 900px;
68
  margin: 0 auto;
69
  padding: 20px;
70
+ background-color: #f5f7fa;
71
  }}
72
  .container {{
73
  background-color: white;
74
+ padding: 50px;
75
+ border-radius: 12px;
76
+ box-shadow: 0 5px 15px rgba(0, 0, 0, 0.08);
77
  }}
78
  .header {{
79
  text-align: center;
80
+ border-bottom: 4px solid #4CAF50;
81
+ padding-bottom: 25px;
82
+ margin-bottom: 40px;
83
  }}
84
  .header h1 {{
85
  color: #2c3e50;
86
  margin: 0;
87
+ font-size: 2.8em;
88
+ font-weight: 700;
89
  }}
90
  .header .subtitle {{
91
  color: #7f8c8d;
92
  font-style: italic;
93
  margin-top: 10px;
94
+ font-size: 1.1em;
95
  }}
96
  .problem-section {{
97
+ background-color: #e8f5e9;
98
+ padding: 25px;
99
+ border-radius: 10px;
100
+ margin-bottom: 35px;
101
+ border-left: 6px solid #4CAF50;
102
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
103
  }}
104
  .problem-section h2 {{
105
  color: #2c3e50;
106
  margin-top: 0;
107
+ font-size: 1.6em;
108
+ }}
109
+ .problem-section p {{
110
+ font-size: 1.1em;
111
+ line-height: 1.6;
112
  }}
113
  .solution-content {{
114
+ background-color: #fafbfc;
115
+ padding: 30px;
116
+ border-radius: 10px;
117
+ border-left: 6px solid #007bff;
118
+ box-shadow: 0 2px 5px rgba(0,0,0,0.05);
119
  }}
120
  h1, h2, h3, h4, h5, h6 {{
121
  color: #2c3e50;
122
+ margin-top: 30px;
123
  margin-bottom: 15px;
124
+ font-weight: 600;
125
  }}
126
  h2 {{
127
+ border-bottom: 2px solid #e1e4e8;
128
+ padding-bottom: 12px;
129
+ font-size: 1.8em;
130
+ }}
131
+ h3 {{
132
+ font-size: 1.4em;
133
+ color: #34495e;
134
+ }}
135
+ h4 {{
136
+ font-size: 1.2em;
137
+ color: #34495e;
138
  }}
139
  code {{
140
+ background-color: #f1f3f5;
141
+ padding: 3px 8px;
142
+ border-radius: 4px;
143
+ font-family: 'Courier New', Consolas, monospace;
144
+ color: #e83e8c;
145
+ font-size: 0.9em;
146
  }}
147
  pre {{
148
+ background-color: #f6f8fa;
149
+ padding: 20px;
150
+ border-radius: 6px;
151
  overflow-x: auto;
152
+ border: 1px solid #d1d5da;
153
+ line-height: 1.6;
154
  }}
155
  pre code {{
156
  background-color: transparent;
157
  padding: 0;
158
+ color: #24292e;
159
  }}
160
  .math-expression {{
161
+ background-color: #fff9e6;
162
+ padding: 15px;
163
+ border-radius: 6px;
164
+ border: 1px solid #ffe066;
165
+ margin: 15px 0;
166
+ text-align: center;
167
+ font-size: 1.15em;
168
  }}
169
  .step {{
170
+ margin: 25px 0;
171
+ padding: 20px;
172
  background-color: #ffffff;
173
  border-radius: 8px;
174
  border: 1px solid #dee2e6;
175
+ box-shadow: 0 1px 3px rgba(0,0,0,0.05);
176
  }}
177
  .final-answer {{
178
  background-color: #d4edda;
179
+ border: 3px solid #28a745;
180
+ padding: 25px;
181
+ border-radius: 10px;
182
+ margin-top: 35px;
183
  text-align: center;
184
+ font-size: 1.3em;
185
+ }}
186
+ .final-answer h2, .final-answer h3 {{
187
+ color: #155724;
188
+ margin-top: 0;
189
  }}
190
  .timestamp {{
191
  text-align: right;
192
  color: #6c757d;
193
+ font-size: 0.95em;
194
+ margin-top: 40px;
195
+ padding-top: 25px;
196
+ border-top: 2px solid #e9ecef;
197
  }}
198
  ul, ol {{
199
+ padding-left: 30px;
200
+ line-height: 1.8;
201
  }}
202
  li {{
203
+ margin: 10px 0;
204
  }}
205
  table {{
206
  border-collapse: collapse;
207
  width: 100%;
208
+ margin: 25px 0;
209
+ box-shadow: 0 1px 3px rgba(0,0,0,0.1);
210
  }}
211
  th, td {{
212
+ border: 1px solid #dee2e6;
213
+ padding: 14px;
214
  text-align: left;
215
  }}
216
  th {{
217
  background-color: #f8f9fa;
218
+ font-weight: 600;
219
+ color: #495057;
220
+ }}
221
+ tr:nth-child(even) {{
222
+ background-color: #f8f9fa;
223
  }}
224
  .print-button {{
225
  background-color: #007bff;
226
  color: white;
227
  border: none;
228
+ padding: 12px 24px;
229
+ border-radius: 6px;
230
  cursor: pointer;
231
  font-size: 16px;
232
  margin: 10px 5px;
233
  display: inline-block;
234
  text-decoration: none;
235
+ font-weight: 500;
236
+ transition: background-color 0.2s;
237
  }}
238
  .print-button:hover {{
239
  background-color: #0056b3;
240
  }}
241
+
242
+ /* Math styling */
243
+ mjx-container {{
244
+ margin: 10px 0 !important;
245
+ }}
246
+
247
+ mjx-container[display="true"] {{
248
+ margin: 20px 0 !important;
249
+ }}
250
+
251
+ /* Boxed answers */
252
+ .boxed {{
253
+ border: 2px solid #4CAF50;
254
+ padding: 10px 15px;
255
+ border-radius: 5px;
256
+ display: inline-block;
257
+ background-color: #f0f9f0;
258
+ }}
259
+
260
  @media print {{
261
  body {{
262
  background-color: white;
 
264
  .container {{
265
  box-shadow: none;
266
  border: none;
267
+ padding: 20px;
268
  }}
269
  .print-button {{
270
  display: none;
 
275
  function printPage() {{
276
  window.print();
277
  }}
278
+
279
+ // Wait for MathJax to finish rendering before showing content
280
+ window.addEventListener('load', function() {{
281
+ if (window.MathJax) {{
282
+ MathJax.startup.promise.then(function () {{
283
+ console.log('MathJax rendering complete');
284
+ }});
285
+ }}
286
+ }});
287
  </script>
288
  </head>
289
  <body>
 
332
 
333
  return file_path
334
 
335
+ # Function to convert HTML to PDF with proper math rendering
336
  def html_to_pdf(html_content, filename_prefix="math_solution"):
337
  """Convert HTML content to PDF and return the file path"""
338
  timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
 
343
  pdf_path = os.path.join(temp_dir, filename)
344
 
345
  try:
346
+ # Note: WeasyPrint doesn't support MathJax rendering
347
+ # For PDF with proper math, we need to use a different approach
348
+ # This creates a basic PDF - for proper math rendering in PDF,
349
+ # consider using tools like puppeteer or selenium with headless browser
350
  weasyprint.HTML(string=html_content).write_pdf(pdf_path)
351
  return pdf_path
352
  except Exception as e:
 
372
  """You are an expert math tutor who explains concepts clearly and thoroughly.
373
  Analyze the given math problem and provide a detailed step-by-step solution.
374
  For each step:
375
+ 1. Show the mathematical operation using proper LaTeX notation wrapped in \\[ \\] for display math or \\( \\) for inline math
376
  2. Explain why this step is necessary
377
  3. Connect it to relevant mathematical concepts
378
 
379
+ IMPORTANT: Use proper LaTeX notation for all mathematical expressions:
380
+ - Use \\[ ... \\] for display (centered) equations
381
+ - Use \\( ... \\) for inline math
382
+ - Use \\boxed{} for final answers
383
+ - Use \\text{} for text within math mode
384
+ - Example: \\[ A = \\pi r^{2} \\]
385
+ - Example: The area \\( A \\) equals \\( \\pi r^{2} \\)
386
+
387
  Format your response using markdown with clear section headers.
388
  Begin with an "Initial Analysis" section, follow with numbered steps,
389
  and conclude with a "Final Answer" section.
 
391
  Use proper markdown formatting including:
392
  - Headers (##, ###)
393
  - **Bold text** for important points
 
394
  - Lists and numbered steps
395
  - Tables if needed for comparisons or data"""},
396
  ]
 
399
  if history:
400
  for exchange in history:
401
  messages.append({"role": "user", "content": exchange[0]})
402
+ if len(exchange) > 1 and exchange[1]:
403
  messages.append({"role": "assistant", "content": exchange[1]})
404
 
405
  # Add the current problem
 
407
 
408
  # Create the completion
409
  completion = client.chat.completions.create(
410
+ model="deepseek/deepseek-r1-0528:free",
411
  messages=messages,
412
  extra_headers={
413
  "HTTP-Referer": "https://advancedmathtutor.edu",
 
455
  "content": """You are an expert math tutor who explains concepts clearly and thoroughly.
456
  Analyze the given math problem and provide a detailed step-by-step solution.
457
  For each step:
458
+ 1. Show the mathematical operation using proper LaTeX notation wrapped in \\[ \\] for display math or \\( \\) for inline math
459
  2. Explain why this step is necessary
460
  3. Connect it to relevant mathematical concepts
461
 
462
+ IMPORTANT: Use proper LaTeX notation for all mathematical expressions:
463
+ - Use \\[ ... \\] for display (centered) equations
464
+ - Use \\( ... \\) for inline math
465
+ - Use \\boxed{} for final answers
466
+ - Use \\text{} for text within math mode
467
+ - Example: \\[ A = \\pi r^{2} \\]
468
+ - Example: The area \\( A \\) equals \\( \\pi r^{2} \\)
469
+
470
  Format your response using markdown with clear section headers.
471
  Begin with an "Initial Analysis" section, follow with numbered steps,
472
  and conclude with a "Final Answer" section.
 
474
  Use proper markdown formatting including:
475
  - Headers (##, ###)
476
  - **Bold text** for important points
 
477
  - Lists and numbered steps
478
  - Tables if needed for comparisons or data"""
479
  }
 
483
  if history:
484
  for exchange in history:
485
  messages.append({"role": "user", "content": exchange[0]})
486
+ if len(exchange) > 1 and exchange[1]:
487
  messages.append({"role": "assistant", "content": exchange[1]})
488
 
489
  # Prepare the user message content
 
538
  # Convert to PDF
539
  pdf_file_path = html_to_pdf(html_solution, "together_solution")
540
 
541
+ # Update history
542
  if history is None:
543
  history = []
544
  history.append((problem_display, markdown_solution))
 
567
  gr.Markdown("# 📚 Advanced Math Tutor")
568
  gr.Markdown("""
569
  This application provides step-by-step solutions to math problems using advanced AI models.
570
+ Solutions are generated in **HTML format** with proper mathematical notation rendering using MathJax.
571
+ Choose between OpenRouter or Together AI for problem solving.
 
572
  """)
573
 
574
  # Main tabs
 
592
  ["Solve the quadratic equation: 3x² + 5x - 2 = 0"],
593
  ["Find the derivative of f(x) = x³ln(x)"],
594
  ["Calculate the area of a circle with radius 5 cm"],
595
+ ["Find all values of x that satisfy: log₂(x-1) + log₂(x+3) = 5"]
596
  ],
597
  inputs=[text_problem_input],
598
  label="Example Problems"
 
602
  openrouter_clear_btn = gr.Button("Clear")
603
 
604
  with gr.Column(scale=2):
605
+ openrouter_solution_output = gr.HTML(label="Solution (HTML with LaTeX)")
606
 
607
  with gr.Row():
608
  openrouter_html_download = gr.File(
 
614
  visible=False
615
  )
616
 
 
617
  openrouter_conversation_history = gr.State(value=None)
618
 
 
619
  def handle_openrouter_submit(api_key, problem_text, history):
620
  html_solution, html_file, pdf_file, updated_history = generate_math_solution_openrouter(
621
  api_key, problem_text, history
622
  )
623
 
 
624
  return (
625
  html_solution,
626
  updated_history,
 
669
  )
670
  together_problem_input = gr.Textbox(
671
  label="Problem Description (Optional)",
672
+ placeholder="Enter additional context...",
673
  lines=3
674
  )
675
  together_image_input = gr.Image(
 
681
  together_clear_btn = gr.Button("Clear")
682
 
683
  with gr.Column(scale=2):
684
+ together_solution_output = gr.HTML(label="Solution (HTML with LaTeX)")
685
 
686
  with gr.Row():
687
  together_html_download = gr.File(
 
693
  visible=False
694
  )
695
 
 
696
  together_conversation_history = gr.State(value=None)
697
 
 
698
  def handle_together_submit(api_key, problem_text, image_path, history):
699
  html_solution, html_file, pdf_file, updated_history = generate_math_solution_together(
700
  api_key, problem_text, image_path, history
701
  )
702
 
 
703
  return (
704
  html_solution,
705
  updated_history,
 
742
  gr.Markdown("""
743
  ## How to Use the Advanced Math Tutor
744
 
745
+ ### Key Features 🎉
746
+ - **Professional math rendering**: All equations rendered using MathJax/LaTeX
747
+ - **HTML-formatted solutions**: Beautiful, readable format
748
+ - **Download HTML**: Save solutions as HTML files with proper math notation
749
+ - **Download PDF**: Convert solutions to PDF (Note: PDF math rendering may vary)
750
+ - **Print functionality**: Print directly from your browser
751
 
752
  ### Getting Started
753
 
754
+ #### For Text Problems (OpenRouter)
755
+ 1. Get API key from [OpenRouter](https://openrouter.ai/)
756
+ 2. Enter your problem in proper notation
757
+ 3. Get beautifully formatted solutions with proper mathematical notation
758
 
759
+ #### For Image Problems (Together AI)
760
+ 1. Get API key from [Together AI](https://www.together.ai/)
761
+ 2. Upload a clear image of the math problem
762
+ 3. Optionally add context
 
 
763
 
764
+ ### Math Notation Tips
765
+ - Superscripts: or x^2
766
+ - Subscripts: x₁ or x_1
767
+ - Fractions: Use / or describe as "numerator over denominator"
768
+ - Greek letters: pi, alpha, beta, theta, etc.
769
+ - Square roots: or sqrt()
770
 
771
+ ### Types of Problems
772
+ - Algebra, Calculus, Trigonometry
773
+ - Geometry, Statistics
774
+ - Number Theory, Linear Algebra
775
+ - And much more!
 
776
 
777
+ ### Note on PDF Export
778
+ The HTML version will always have perfect math rendering. The PDF export uses
779
+ WeasyPrint which may have limitations with complex math notation. For best results,
780
+ use the "Print to PDF" button in the HTML view instead.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
781
  """)
782
 
 
783
  gr.Markdown("""
784
  ---
785
  ### About
786
+ Enhanced with **MathJax** for professional mathematical notation rendering.
787
+ Your API keys are never stored permanently.
 
 
 
 
 
 
 
 
 
788
  """)
789
 
790
  return demo