MasteredUltraInstinct commited on
Commit
3aa5fcb
ยท
verified ยท
1 Parent(s): f555e00

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +24 -54
app.py CHANGED
@@ -19,7 +19,6 @@ def clean_latex(latex):
19
  latex = latex.replace('\\\\', '\\')
20
  latex = re.sub(r'\\[ \t\n\r\f\v]*', '', latex)
21
  latex = re.sub(r'\\([+\-=])', r'\1', latex)
22
-
23
  replacements = {
24
  r'\\chi': 'x', r'chi': 'x',
25
  r'\\xi': 'x', r'xi': 'x',
@@ -33,14 +32,11 @@ def clean_latex(latex):
33
  }
34
  for wrong, correct in replacements.items():
35
  latex = re.sub(wrong, correct, latex)
36
-
37
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Xx]\s*\}?', 'x', latex)
38
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Yy]\s*\}?', 'y', latex)
39
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Zz]\s*\}?', 'z', latex)
40
-
41
  latex = latex.replace('cal x', 'x').replace('cal X', 'x')
42
  latex = latex.replace('mathcal x', 'x').replace('mathcal X', 'x')
43
-
44
  latex = latex.replace('{', '').replace('}', '')
45
  latex = latex.strip().rstrip(',.')
46
  latex = re.sub(r'(?<![a-zA-Z0-9])e(?![a-zA-Z0-9])', 'E', latex)
@@ -48,23 +44,17 @@ def clean_latex(latex):
48
  latex = re.sub(r'(\d+)\s*i', r'\1*I', latex)
49
  latex = re.sub(r'(?<![a-zA-Z0-9])i(?![a-zA-Z0-9])', 'I', latex)
50
  latex = re.sub(r'\(([^()]+?)\)\s*([a-zA-Z](\^\d+)?)', r'(\1)*\2', latex)
51
-
52
  latex = latex.replace(r'\cdot', '*')
53
- latex = latex.replace('โˆ’', '-') # Unicode minus
54
  latex = re.sub(r'[^\w\s^=+*\-().]', '', latex)
55
-
56
  if '=' not in latex:
57
  latex += '=0'
58
-
59
  latex = latex.replace('pi', '3.1416')
60
  latex = latex.replace('e', '2.7183')
61
-
62
  return latex
63
 
64
  def request_llm_fallback(bad_latex, llm_url):
65
- pre_cleaned = re.sub(
66
- r'(\\!?pm|\\not=?|\\!|\\L|\\perp|\\bar|\\Sigma|\\boldmath|G|L(?=\^))', '', bad_latex
67
- )
68
  try:
69
  response = requests.post(f"{llm_url}/clean", json={"prompt": pre_cleaned})
70
  if response.status_code == 200:
@@ -87,16 +77,12 @@ def solve_polynomial(image, llm_url):
87
  try:
88
  img = preprocess_handwritten_image(image)
89
  latex_result = model(img)
90
-
91
  if not latex_result or len(latex_result.strip()) < 2:
92
  return "โŒ Could not extract valid LaTeX from image.", "", ""
93
-
94
  cleaned_latex = clean_latex(latex_result)
95
-
96
  try:
97
  expr = parse_latex(cleaned_latex)
98
  expr = expr.subs(sp.pi, sp.Float(3.1416)).subs(sp.E, sp.Float(2.7183))
99
-
100
  if not isinstance(expr, sp.Equality):
101
  raise ValueError("Expression is not an equation.")
102
  lhs_minus_rhs = expr.lhs - expr.rhs
@@ -112,7 +98,6 @@ def solve_polynomial(image, llm_url):
112
  try:
113
  expr = parse_latex(cleaned_latex)
114
  expr = expr.subs(sp.pi, sp.Float(3.1416)).subs(sp.E, sp.Float(2.7183))
115
-
116
  if not isinstance(expr, sp.Equality):
117
  raise ValueError("Expression is not an equation.")
118
  lhs_minus_rhs = expr.lhs - expr.rhs
@@ -123,25 +108,17 @@ def solve_polynomial(image, llm_url):
123
  raise ValueError("Expression contains junk symbols.")
124
  except Exception:
125
  expr = None
126
-
127
  if expr is None:
128
- return (
129
- f"โŒ Could not parse expression even after fallback:\n\n```latex\n{cleaned_latex}\n```",
130
- cleaned_latex,
131
- ""
132
- )
133
-
134
  output = (
135
  f"## ๐Ÿ“„ Extracted LaTeX\n\n```latex\n{latex_result}\n```\n"
136
  f"\n---\n## ๐Ÿงน Cleaned LaTeX Used\n\n```latex\n{cleaned_latex}\n```\n"
137
  f"\n---\n## ๐Ÿง  Parsed Expression\n\n$$ {sp.latex(expr)} $$\n\n---\n"
138
  )
139
-
140
  if isinstance(expr, sp.Equality):
141
  lhs = expr.lhs - expr.rhs
142
  output += f"## โœ๏ธ Step 1: Standard Form\n$$ {sp.latex(lhs)} = 0 $$\n---\n"
143
  output += f"## ๐Ÿงฉ Step 2: Factor\n$$ {sp.latex(sp.factor(lhs))} = 0 $$\n---\n"
144
-
145
  x_sym = None
146
  for sym in lhs.free_symbols:
147
  if str(sym) == "x":
@@ -149,9 +126,7 @@ def solve_polynomial(image, llm_url):
149
  break
150
  if x_sym is None:
151
  raise ValueError("โŒ Could not find variable 'x' in the equation.")
152
-
153
  roots = sp.solve(sp.Eq(lhs, 0), x_sym, dict=True)
154
-
155
  output += "## โœ… Step 3: Solve Roots\n"
156
  if roots:
157
  output += "$$\n\\begin{aligned}\n"
@@ -163,9 +138,7 @@ def solve_polynomial(image, llm_url):
163
  else:
164
  simplified = sp.simplify(expr)
165
  output += f"## โž• Simplified Expression\n$$ {sp.latex(simplified)} $$"
166
-
167
  return output, cleaned_latex, ""
168
-
169
  except Exception as e:
170
  return f"โŒ **Error**: {str(e)}", "", ""
171
 
@@ -173,49 +146,46 @@ def wrapped_solver(img, url):
173
  result, cleaned, _ = solve_polynomial(img, url)
174
  return result, cleaned
175
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
  with gr.Blocks() as demo:
177
  with gr.Tab("๐Ÿ–ผ๏ธ Parse from Image"):
178
  llm_url = gr.Textbox(label="๐Ÿ”— Enter LLM Microservice URL (from Colab)", placeholder="https://xxxx.ngrok-free.app")
179
  image_input = gr.Image(type="pil", label="๐Ÿ“ท Upload Image of Polynomial")
180
  hidden_latex = gr.Textbox(visible=False)
181
-
182
  output_box = gr.Markdown(label="๐Ÿ“‹ Step-by-step Solution")
183
  submit_btn = gr.Button("๐Ÿ” Solve")
184
  submit_btn.click(fn=wrapped_solver, inputs=[image_input, llm_url], outputs=[output_box, hidden_latex])
185
-
186
  explain_box = gr.Markdown(label="๐Ÿ—ฃ๏ธ Human-style Explanation")
187
  explain_btn = gr.Button("๐Ÿง  Explain Human-Solution")
188
  explain_btn.click(fn=request_llm_explanation, inputs=[hidden_latex, llm_url], outputs=explain_box)
189
-
190
  demo.title = "๐Ÿง  Polynomial Solver from Image"
191
  demo.description = "Upload a polynomial image (typed or handwritten). View symbolic steps and human-style explanation."
192
 
193
- with demo:
194
  with gr.Tab("๐Ÿงฎ Solve by Coefficients"):
195
  degree_input = gr.Number(label="Enter Degree of Polynomial (e.g. 3)")
196
  coeffs_input = gr.Textbox(label="Enter Coefficients (comma-separated)", placeholder="e.g. 1, 2, 0, -4")
197
  roots_output = gr.Markdown(label="โœ… Roots")
198
-
199
- def solve_from_coeffs(degree, coeff_str):
200
- try:
201
- coeffs = [float(c.strip()) for c in coeff_str.split(",")]
202
- if len(coeffs) != int(degree) + 1:
203
- return f"โŒ You entered {len(coeffs)} coefficients, but degree {degree} needs {int(degree)+1}."
204
-
205
- x = sp.Symbol("x")
206
- poly_expr = sum(coeffs[i] * x**(int(degree) - i) for i in range(len(coeffs)))
207
- roots = sp.solve(poly_expr, x)
208
-
209
- result = "### Roots:\n"
210
- for i, r in enumerate(roots, 1):
211
- result += f"- Root {i}: $${sp.latex(sp.N(r, 6))}$$\n"
212
- return result
213
- except Exception as e:
214
- return f"โŒ Error: {str(e)}"
215
-
216
  coeff_btn = gr.Button("๐Ÿ“Œ Solve")
217
- coeff_btn.click(fn=solve_from_coeffs, inputs=[degree_input, coeffs_input], outputs=roots_output)
 
 
 
218
 
219
  if __name__ == "__main__":
220
  demo.launch()
221
-
 
19
  latex = latex.replace('\\\\', '\\')
20
  latex = re.sub(r'\\[ \t\n\r\f\v]*', '', latex)
21
  latex = re.sub(r'\\([+\-=])', r'\1', latex)
 
22
  replacements = {
23
  r'\\chi': 'x', r'chi': 'x',
24
  r'\\xi': 'x', r'xi': 'x',
 
32
  }
33
  for wrong, correct in replacements.items():
34
  latex = re.sub(wrong, correct, latex)
 
35
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Xx]\s*\}?', 'x', latex)
36
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Yy]\s*\}?', 'y', latex)
37
  latex = re.sub(r'\\(cal|mathcal)\s*\{?\s*[Zz]\s*\}?', 'z', latex)
 
38
  latex = latex.replace('cal x', 'x').replace('cal X', 'x')
39
  latex = latex.replace('mathcal x', 'x').replace('mathcal X', 'x')
 
40
  latex = latex.replace('{', '').replace('}', '')
41
  latex = latex.strip().rstrip(',.')
42
  latex = re.sub(r'(?<![a-zA-Z0-9])e(?![a-zA-Z0-9])', 'E', latex)
 
44
  latex = re.sub(r'(\d+)\s*i', r'\1*I', latex)
45
  latex = re.sub(r'(?<![a-zA-Z0-9])i(?![a-zA-Z0-9])', 'I', latex)
46
  latex = re.sub(r'\(([^()]+?)\)\s*([a-zA-Z](\^\d+)?)', r'(\1)*\2', latex)
 
47
  latex = latex.replace(r'\cdot', '*')
48
+ latex = latex.replace('โˆ’', '-')
49
  latex = re.sub(r'[^\w\s^=+*\-().]', '', latex)
 
50
  if '=' not in latex:
51
  latex += '=0'
 
52
  latex = latex.replace('pi', '3.1416')
53
  latex = latex.replace('e', '2.7183')
 
54
  return latex
55
 
56
  def request_llm_fallback(bad_latex, llm_url):
57
+ pre_cleaned = re.sub(r'(\\!?pm|\\not=?|\\!|\\L|\\perp|\\bar|\\Sigma|\\boldmath|G|L(?=\^))', '', bad_latex)
 
 
58
  try:
59
  response = requests.post(f"{llm_url}/clean", json={"prompt": pre_cleaned})
60
  if response.status_code == 200:
 
77
  try:
78
  img = preprocess_handwritten_image(image)
79
  latex_result = model(img)
 
80
  if not latex_result or len(latex_result.strip()) < 2:
81
  return "โŒ Could not extract valid LaTeX from image.", "", ""
 
82
  cleaned_latex = clean_latex(latex_result)
 
83
  try:
84
  expr = parse_latex(cleaned_latex)
85
  expr = expr.subs(sp.pi, sp.Float(3.1416)).subs(sp.E, sp.Float(2.7183))
 
86
  if not isinstance(expr, sp.Equality):
87
  raise ValueError("Expression is not an equation.")
88
  lhs_minus_rhs = expr.lhs - expr.rhs
 
98
  try:
99
  expr = parse_latex(cleaned_latex)
100
  expr = expr.subs(sp.pi, sp.Float(3.1416)).subs(sp.E, sp.Float(2.7183))
 
101
  if not isinstance(expr, sp.Equality):
102
  raise ValueError("Expression is not an equation.")
103
  lhs_minus_rhs = expr.lhs - expr.rhs
 
108
  raise ValueError("Expression contains junk symbols.")
109
  except Exception:
110
  expr = None
 
111
  if expr is None:
112
+ return f"โŒ Could not parse expression even after fallback:\n\n```latex\n{cleaned_latex}\n```", cleaned_latex, ""
 
 
 
 
 
113
  output = (
114
  f"## ๐Ÿ“„ Extracted LaTeX\n\n```latex\n{latex_result}\n```\n"
115
  f"\n---\n## ๐Ÿงน Cleaned LaTeX Used\n\n```latex\n{cleaned_latex}\n```\n"
116
  f"\n---\n## ๐Ÿง  Parsed Expression\n\n$$ {sp.latex(expr)} $$\n\n---\n"
117
  )
 
118
  if isinstance(expr, sp.Equality):
119
  lhs = expr.lhs - expr.rhs
120
  output += f"## โœ๏ธ Step 1: Standard Form\n$$ {sp.latex(lhs)} = 0 $$\n---\n"
121
  output += f"## ๐Ÿงฉ Step 2: Factor\n$$ {sp.latex(sp.factor(lhs))} = 0 $$\n---\n"
 
122
  x_sym = None
123
  for sym in lhs.free_symbols:
124
  if str(sym) == "x":
 
126
  break
127
  if x_sym is None:
128
  raise ValueError("โŒ Could not find variable 'x' in the equation.")
 
129
  roots = sp.solve(sp.Eq(lhs, 0), x_sym, dict=True)
 
130
  output += "## โœ… Step 3: Solve Roots\n"
131
  if roots:
132
  output += "$$\n\\begin{aligned}\n"
 
138
  else:
139
  simplified = sp.simplify(expr)
140
  output += f"## โž• Simplified Expression\n$$ {sp.latex(simplified)} $$"
 
141
  return output, cleaned_latex, ""
 
142
  except Exception as e:
143
  return f"โŒ **Error**: {str(e)}", "", ""
144
 
 
146
  result, cleaned, _ = solve_polynomial(img, url)
147
  return result, cleaned
148
 
149
+ def solve_from_coeffs(degree, coeff_str):
150
+ try:
151
+ coeffs = [float(c.strip()) for c in coeff_str.split(",")]
152
+ if len(coeffs) != int(degree) + 1:
153
+ return f"โŒ You entered {len(coeffs)} coefficients, but degree {degree} needs {int(degree)+1}.", ""
154
+ x = sp.Symbol("x")
155
+ poly_expr = sum(coeffs[i] * x**(int(degree) - i) for i in range(len(coeffs)))
156
+ latex = sp.latex(sp.Eq(poly_expr, 0))
157
+ roots = sp.solve(poly_expr, x)
158
+ result = "## ๐Ÿงฎ Symbolic Roots:\n"
159
+ for i, r in enumerate(roots, 1):
160
+ result += f"- Root {i}: $${sp.latex(sp.N(r, 6))}$$\n"
161
+ return result, latex
162
+ except Exception as e:
163
+ return f"โŒ Error: {str(e)}", ""
164
+
165
  with gr.Blocks() as demo:
166
  with gr.Tab("๐Ÿ–ผ๏ธ Parse from Image"):
167
  llm_url = gr.Textbox(label="๐Ÿ”— Enter LLM Microservice URL (from Colab)", placeholder="https://xxxx.ngrok-free.app")
168
  image_input = gr.Image(type="pil", label="๐Ÿ“ท Upload Image of Polynomial")
169
  hidden_latex = gr.Textbox(visible=False)
 
170
  output_box = gr.Markdown(label="๐Ÿ“‹ Step-by-step Solution")
171
  submit_btn = gr.Button("๐Ÿ” Solve")
172
  submit_btn.click(fn=wrapped_solver, inputs=[image_input, llm_url], outputs=[output_box, hidden_latex])
 
173
  explain_box = gr.Markdown(label="๐Ÿ—ฃ๏ธ Human-style Explanation")
174
  explain_btn = gr.Button("๐Ÿง  Explain Human-Solution")
175
  explain_btn.click(fn=request_llm_explanation, inputs=[hidden_latex, llm_url], outputs=explain_box)
 
176
  demo.title = "๐Ÿง  Polynomial Solver from Image"
177
  demo.description = "Upload a polynomial image (typed or handwritten). View symbolic steps and human-style explanation."
178
 
 
179
  with gr.Tab("๐Ÿงฎ Solve by Coefficients"):
180
  degree_input = gr.Number(label="Enter Degree of Polynomial (e.g. 3)")
181
  coeffs_input = gr.Textbox(label="Enter Coefficients (comma-separated)", placeholder="e.g. 1, 2, 0, -4")
182
  roots_output = gr.Markdown(label="โœ… Roots")
183
+ coeff_hidden_latex = gr.Textbox(visible=False)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
  coeff_btn = gr.Button("๐Ÿ“Œ Solve")
185
+ coeff_btn.click(fn=solve_from_coeffs, inputs=[degree_input, coeffs_input], outputs=[roots_output, coeff_hidden_latex])
186
+ coeff_explain_box = gr.Markdown(label="๐Ÿ—ฃ๏ธ Human-style Explanation")
187
+ coeff_explain_btn = gr.Button("๐Ÿง  Explain Human-Solution")
188
+ coeff_explain_btn.click(fn=request_llm_explanation, inputs=[coeff_hidden_latex, llm_url], outputs=coeff_explain_box)
189
 
190
  if __name__ == "__main__":
191
  demo.launch()