aciang commited on
Commit
0531f23
·
verified ·
1 Parent(s): e87a45f

Hotfix: remove star-insertion; rely on implicit_multiplication_application

Browse files
Files changed (1) hide show
  1. app.py +17 -25
app.py CHANGED
@@ -1,4 +1,4 @@
1
- \
2
  import re
3
  import gradio as gr
4
  import sympy as sp
@@ -9,34 +9,27 @@ from sympy.parsing.sympy_parser import (
9
 
10
  TITLE = "LanguageBridge — Math Fast Agent (SymPy)"
11
 
12
- # ---- 正規化:全形→半形、√→sqrt、^→**、自動補乘號(隱式→顯式) ----
13
  def normalize_ascii(s: str) -> str:
14
  table = str.maketrans({
15
- '':'(', '':')', '':',', '':';', '':':',
16
- '':'=', '':'-', '':'+', '':'*', '':'/', '':'.',
17
- '×':'*', '':'sqrt'
18
  })
19
  return s.translate(table)
20
 
21
- def auto_insert_stars(s: str) -> str:
22
- s = re.sub(r'(\d)([A-Za-z])', r'\1*\2', s) # 3x -> 3*x
23
- s = re.sub(r'([A-Za-z0-9_])\(', r'\1*(', s) # x( -> x*(
24
- s = re.sub(r'\)([A-Za-z0-9_])', r')*\1', s) # )x -> )*x
25
- s = re.sub(r'(\d)\s*sqrt', r'\1*sqrt', s) # 2sqrt -> 2*sqrt
26
- return s
27
-
28
  def preprocess(expr: str) -> str:
29
  s = (expr or "").strip()
30
  s = normalize_ascii(s)
31
- s = s.replace("^", "**") # 2^3 -> 2**3
32
- s = auto_insert_stars(s) # 隱式乘法補 *
33
  return s
34
 
 
35
  TRANS = standard_transformations + (implicit_multiplication_application, convert_xor)
36
 
37
  def to_sympy_expr(s: str):
38
- s = preprocess(s)
39
- return parse_expr(s, transformations=TRANS)
40
 
41
  def to_sympy_eq(s: str):
42
  s = preprocess(s)
@@ -49,32 +42,32 @@ def to_sympy_eq(s: str):
49
  def solve_math(q: str):
50
  q = (q or "").strip()
51
  if not q:
52
- return "請輸入算式或方程,例如:3x+7=1;sin(x)^2 + cos(x)^2;factor(x^4-1)"
53
 
54
  try:
55
- # 允許多行或分號分隔
56
  parts = [s.strip() for seg in q.split(";") for s in seg.split("\n")]
57
  parts = [p for p in parts if p]
58
 
59
- # '=' :解方程(可聯立)
60
  if any("=" in p for p in parts):
61
  eqs, syms = [], set()
62
  for s in parts:
63
  if "=" in s:
64
  e = to_sympy_eq(s)
65
  eqs.append(e)
66
- syms |= e.free_symbols | e.rhs.free_symbols
67
  if not syms:
68
  syms = {sp.symbols("x")}
69
  sol = sp.solve(eqs, list(syms), dict=True)
70
  if not sol:
71
  return "無解或需要更多條件。"
72
- return "\\n".join(
73
  f"解 {i}: " + ", ".join([f"{k} = {sp.simplify(v)}" for k, v in d.items()])
74
  for i, d in enumerate(sol, 1)
75
  )
76
 
77
- # 否則視為一般表達式:簡化/因式/微分/積分
78
  expr = to_sympy_expr(q)
79
  out = []
80
  try: out.append(f"簡化:{sp.simplify(expr)}")
@@ -88,7 +81,7 @@ def solve_math(q: str):
88
  out.append(f"對 {x} 微分:{sp.diff(expr, x)}")
89
  out.append(f"對 {x} 積分:{sp.integrate(expr, x)}")
90
  except Exception: pass
91
- return "\\n".join(out) if out else f"結果:{expr}"
92
 
93
  except Exception as e:
94
  return f"解析失敗:{e}"
@@ -96,8 +89,7 @@ def solve_math(q: str):
96
  with gr.Blocks(title=TITLE) as demo:
97
  gr.Markdown(
98
  "## " + TITLE + "\\n"
99
- "貼上算式(可多行 / `;` 分隔)。支援:隱式乘法 `3x`, `2(x+1)`, `(x)(x+1)`, `2sqrt(x)`;"
100
- "`x^2` 自動轉 `x**2`,`√(x)` 自動轉 `sqrt(x)`。"
101
  )
102
  q = gr.Textbox(lines=6, label="題目 / 算式(可含聯立方程)")
103
  out = gr.Textbox(lines=12, label="輸出")
 
1
+
2
  import re
3
  import gradio as gr
4
  import sympy as sp
 
9
 
10
  TITLE = "LanguageBridge — Math Fast Agent (SymPy)"
11
 
12
+ # ---- 僅做安全正規化:全形→半形、^→**、√→sqrt ----
13
  def normalize_ascii(s: str) -> str:
14
  table = str.maketrans({
15
+ "":"(", "":")", "":",", "":";", "":":",
16
+ "":"=", "":"-", "":"+", "":"*", "":"/", "":".",
17
+ "×":"*", "":"sqrt"
18
  })
19
  return s.translate(table)
20
 
 
 
 
 
 
 
 
21
  def preprocess(expr: str) -> str:
22
  s = (expr or "").strip()
23
  s = normalize_ascii(s)
24
+ s = s.replace("^", "**") # 2^3 -> 2**3
25
+ # 不再自動補 *,避免把 sin(x) 變成 sin*(x)
26
  return s
27
 
28
+ # SymPy 解析:啟用隱式乘法與 ^ 號處理
29
  TRANS = standard_transformations + (implicit_multiplication_application, convert_xor)
30
 
31
  def to_sympy_expr(s: str):
32
+ return parse_expr(preprocess(s), transformations=TRANS)
 
33
 
34
  def to_sympy_eq(s: str):
35
  s = preprocess(s)
 
42
  def solve_math(q: str):
43
  q = (q or "").strip()
44
  if not q:
45
+ return "請輸入算式或方程,例如:3x+7=1;sin(x)^2+cos(x)^2;factor(x^4-1)"
46
 
47
  try:
48
+ # 多行 / 分號;分隔
49
  parts = [s.strip() for seg in q.split(";") for s in seg.split("\n")]
50
  parts = [p for p in parts if p]
51
 
52
+ # 任何一行有 '=' → 解(可聯立)
53
  if any("=" in p for p in parts):
54
  eqs, syms = [], set()
55
  for s in parts:
56
  if "=" in s:
57
  e = to_sympy_eq(s)
58
  eqs.append(e)
59
+ syms |= e.free_symbols | getattr(e, "rhs", sp.Integer(0)).free_symbols
60
  if not syms:
61
  syms = {sp.symbols("x")}
62
  sol = sp.solve(eqs, list(syms), dict=True)
63
  if not sol:
64
  return "無解或需要更多條件。"
65
+ return "\n".join(
66
  f"解 {i}: " + ", ".join([f"{k} = {sp.simplify(v)}" for k, v in d.items()])
67
  for i, d in enumerate(sol, 1)
68
  )
69
 
70
+ # 否則:一般表達式(簡化/因式/微分/積分)
71
  expr = to_sympy_expr(q)
72
  out = []
73
  try: out.append(f"簡化:{sp.simplify(expr)}")
 
81
  out.append(f"對 {x} 微分:{sp.diff(expr, x)}")
82
  out.append(f"對 {x} 積分:{sp.integrate(expr, x)}")
83
  except Exception: pass
84
+ return "\n".join(out) if out else f"結果:{expr}"
85
 
86
  except Exception as e:
87
  return f"解析失敗:{e}"
 
89
  with gr.Blocks(title=TITLE) as demo:
90
  gr.Markdown(
91
  "## " + TITLE + "\\n"
92
+ "貼上算式(可多行 / 分號 `;` 分隔)。支援隱式乘法(例:`3x`, `2(x+1)`, `(x+1)(x-1)`, `2sqrt(x)`)與 `^`。"
 
93
  )
94
  q = gr.Textbox(lines=6, label="題目 / 算式(可含聯立方程)")
95
  out = gr.Textbox(lines=12, label="輸出")