diff --git a/script_library/index.json b/script_library/index.json
index d1337e5..c95a8bd 100644
--- a/script_library/index.json
+++ b/script_library/index.json
@@ -1,7 +1,7 @@
{
"format_version": 1,
- "data_version": 98,
- "updated": "2026-04-20T12:32:31.335Z",
+ "data_version": 99,
+ "updated": "2026-04-21T12:29:23.484Z",
"announcement": null,
"categories": [
{
@@ -1631,6 +1631,29 @@
"updated": null,
"status": "active",
"lines": 26
+ },
+ {
+ "id": "3_0_mo8lp3m5",
+ "name": "科学计算器3.0",
+ "name_en": "科学计算器3.0",
+ "desc": "兄弟们!咱们的V3(V2是html上传不了)版本科学计算器也是来了!直接上传,肥肠好用!(直接打开第三条网址)之前不更新是在搞焊接,感谢大伙一路以来的陪伴!",
+ "desc_en": "兄弟们!咱们的V3(V2是html上传不了)版本科学计算器也是来了!直接上传,肥肠好用!(直接打开第三条网址)之前不更新是在搞焊接,感谢大伙一路以来的陪伴!",
+ "category": "ui",
+ "file": "scripts/ui/3_0_mo8lp3m5.py",
+ "thumbnail": null,
+ "version": 1,
+ "file_type": "py",
+ "author": "ENDER",
+ "author_en": "ENDER",
+ "tags": [
+ "community"
+ ],
+ "requires": [],
+ "min_app_version": "1.5.0",
+ "added": "2026-04-21",
+ "updated": null,
+ "status": "active",
+ "lines": 642
}
]
}
diff --git a/script_library/scripts/ui/3_0_mo8lp3m5.py b/script_library/scripts/ui/3_0_mo8lp3m5.py
new file mode 100644
index 0000000..e36bb5d
--- /dev/null
+++ b/script_library/scripts/ui/3_0_mo8lp3m5.py
@@ -0,0 +1,642 @@
+import atlastk
+import math
+import numpy as np
+import re
+
+# 计算器状态
+state = {
+ "display": "0",
+ "expression": "",
+ "memory": {"A": 0, "B": 0, "C": 0, "D": 0, "E": 0, "F": 0, "M": 0},
+ "ans": 0,
+ "angle_mode": "rad", # rad / deg / grad
+ "mode": "basic", # basic / matrix / stats / solver
+ "shift": False,
+ "matrix_a": "",
+ "matrix_b": "",
+ "matrix_result": "",
+ "stats_data": "",
+ "stats_result": "",
+ "history": [],
+ "constants": {
+ "c": 299792458, "g": 9.80665, "h": 6.62607015e-34,
+ "e": math.e, "pi": math.pi, "NA": 6.02214076e23,
+ "k": 1.380649e-23, "R": 8.314462618,
+ },
+}
+
+BODY = """
+
+
+
+
+
+
+
+
+
+
+ 🧮 PRO-991EX
+ RAD
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
矩阵 A
+
+
矩阵 B
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
数据
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+"""
+
+# 辅助函数
+def safe_eval(expr):
+ namespace = {
+ "np": np, "math": math,
+ "sin": math.sin if state["angle_mode"] == "rad" else lambda x: math.sin(math.radians(x)),
+ "cos": math.cos if state["angle_mode"] == "rad" else lambda x: math.cos(math.radians(x)),
+ "tan": math.tan if state["angle_mode"] == "rad" else lambda x: math.tan(math.radians(x)),
+ "asin": math.asin if state["angle_mode"] == "rad" else lambda x: math.degrees(math.asin(x)),
+ "acos": math.acos if state["angle_mode"] == "rad" else lambda x: math.degrees(math.acos(x)),
+ "atan": math.atan if state["angle_mode"] == "rad" else lambda x: math.degrees(math.atan(x)),
+ "log": math.log10, "ln": math.log, "sqrt": math.sqrt,
+ "pi": math.pi, "e": math.e, "factorial": math.factorial,
+ "comb": math.comb, "perm": math.perm,
+ }
+ try:
+ return str(eval(expr, {"__builtins__": {}}, namespace))
+ except Exception as e:
+ return f"错误"
+
+def parse_matrix(text):
+ if not text.strip(): return None
+ rows = text.strip().split(";")
+ return np.array([[float(x.strip()) for x in row.split(",")] for row in rows])
+
+def update_display(dom):
+ dom.setValue("Display", state["display"])
+ dom.setValue("Expression", state["expression"])
+ dom.setValue("AngleIndicator", {"rad": "RAD", "deg": "DEG", "grad": "GRAD"}[state["angle_mode"]])
+
+def update_mode_ui(dom):
+ for m in ["basic", "matrix", "stats", "solver"]:
+ dom.removeClass(f"Mode{m.capitalize()}", "active")
+ dom.setAttribute(f"{m.capitalize()}Panel", "style", f"display: {'block' if m == state['mode'] else 'none'}")
+ dom.addClass(f"Mode{state['mode'].capitalize()}", "active")
+
+def add_history(dom, entry):
+ state["history"].append(entry)
+ if len(state["history"]) > 8: state["history"] = state["history"][-8:]
+ html = "".join(f'{h}
' for h in reversed(state["history"]))
+ dom.inner("HistoryList", html or '就绪
')
+
+# Atlas 回调
+def atk(dom):
+ dom.inner("", BODY)
+ update_display(dom)
+ update_mode_ui(dom)
+
+def atkSetModeBasic(dom): state["mode"] = "basic"; update_mode_ui(dom)
+def atkSetModeMatrix(dom): state["mode"] = "matrix"; update_mode_ui(dom)
+def atkSetModeStats(dom): state["mode"] = "stats"; update_mode_ui(dom)
+def atkSetModeSolver(dom): state["mode"] = "solver"; update_mode_ui(dom)
+
+def atkPressNum0(dom): press_num(dom, "0")
+def atkPressNum1(dom): press_num(dom, "1")
+def atkPressNum2(dom): press_num(dom, "2")
+def atkPressNum3(dom): press_num(dom, "3")
+def atkPressNum4(dom): press_num(dom, "4")
+def atkPressNum5(dom): press_num(dom, "5")
+def atkPressNum6(dom): press_num(dom, "6")
+def atkPressNum7(dom): press_num(dom, "7")
+def atkPressNum8(dom): press_num(dom, "8")
+def atkPressNum9(dom): press_num(dom, "9")
+
+def press_num(dom, num):
+ state["display"] = num if state["display"] in ("0", "错误") else state["display"] + num
+ state["expression"] = state["display"]
+ update_display(dom)
+
+def atkPressDot(dom):
+ if "." not in state["display"]: state["display"] += "."; state["expression"] = state["display"]
+ update_display(dom)
+
+def atkPressAdd(dom): press_op(dom, "+")
+def atkPressSub(dom): press_op(dom, "-")
+def atkPressMul(dom): press_op(dom, "*")
+def atkPressDiv(dom): press_op(dom, "/")
+
+def press_op(dom, op):
+ state["display"] += op; state["expression"] = state["display"]
+ update_display(dom)
+
+def atkPressParen(dom):
+ open_cnt = state["display"].count("("); close_cnt = state["display"].count(")")
+ state["display"] += ")" if open_cnt > close_cnt else "("
+ state["expression"] = state["display"]
+ update_display(dom)
+
+def atkPressSin(dom): press_func(dom, "sin")
+def atkPressCos(dom): press_func(dom, "cos")
+def atkPressTan(dom): press_func(dom, "tan")
+def atkPressAsin(dom): press_func(dom, "asin")
+def atkPressAcos(dom): press_func(dom, "acos")
+def atkPressAtan(dom): press_func(dom, "atan")
+def atkPressLog(dom): press_func(dom, "log")
+def atkPressLn(dom): press_func(dom, "ln")
+def atkPressSqrt(dom): press_func(dom, "sqrt")
+
+def press_func(dom, func):
+ state["display"] = func + "(" if state["display"] == "0" else state["display"] + func + "("
+ state["expression"] = state["display"]
+ update_display(dom)
+
+def atkPressPow(dom): state["display"] += "**"; state["expression"] = state["display"]; update_display(dom)
+def atkPressPi(dom): state["display"] += "pi"; state["expression"] = state["display"]; update_display(dom)
+def atkPressE(dom): state["display"] += "e"; state["expression"] = state["display"]; update_display(dom)
+def atkPressFact(dom): press_func(dom, "factorial")
+def atkPressComb(dom): press_func(dom, "comb")
+def atkPressPerm(dom): press_func(dom, "perm")
+def atkPressAns(dom): state["display"] += str(state["ans"]); state["expression"] = state["display"]; update_display(dom)
+
+def atkToggleAngle(dom):
+ modes = {"rad": "deg", "deg": "grad", "grad": "rad"}
+ state["angle_mode"] = modes[state["angle_mode"]]
+ update_display(dom)
+
+def atkClear(dom):
+ state["display"] = "0"; state["expression"] = ""
+ update_display(dom)
+
+def atkBackspace(dom):
+ state["display"] = state["display"][:-1] or "0"
+ state["expression"] = state["display"]
+ update_display(dom)
+
+def atkCalculate(dom):
+ result = safe_eval(state["display"])
+ try:
+ state["ans"] = float(result)
+ except:
+ pass
+ add_history(dom, f"{state['display']} = {result}")
+ state["display"] = result
+ state["expression"] = ""
+ update_display(dom)
+
+# 矩阵运算
+def atkMatrixAdd(dom): matrix_op(dom, lambda a,b: a+b, "A+B")
+def atkMatrixSub(dom): matrix_op(dom, lambda a,b: a-b, "A-B")
+def atkMatrixMul(dom): matrix_op(dom, lambda a,b: a@b, "A×B")
+
+def matrix_op(dom, op, name):
+ try:
+ a = parse_matrix(dom.getValue("MatrixA"))
+ b = parse_matrix(dom.getValue("MatrixB"))
+ if a is None or b is None:
+ dom.setValue("MatrixResult", "请输入矩阵")
+ return
+ result = op(a, b)
+ dom.setValue("MatrixResult", str(result))
+ add_history(dom, f"{name}: {result}")
+ except Exception as e:
+ dom.setValue("MatrixResult", f"错误: {e}")
+
+def atkMatrixTranspose(dom):
+ try:
+ a = parse_matrix(dom.getValue("MatrixA"))
+ if a is None: dom.setValue("MatrixResult", "请输入矩阵A"); return
+ result = a.T
+ dom.setValue("MatrixResult", str(result))
+ add_history(dom, f"Aᵀ: {result}")
+ except Exception as e:
+ dom.setValue("MatrixResult", f"错误: {e}")
+
+def atkMatrixInv(dom):
+ try:
+ a = parse_matrix(dom.getValue("MatrixA"))
+ if a is None: dom.setValue("MatrixResult", "请输入矩阵A"); return
+ result = np.linalg.inv(a)
+ dom.setValue("MatrixResult", str(result))
+ add_history(dom, f"A⁻¹: {result}")
+ except Exception as e:
+ dom.setValue("MatrixResult", f"不可逆: {e}")
+
+def atkMatrixDet(dom):
+ try:
+ a = parse_matrix(dom.getValue("MatrixA"))
+ result = np.linalg.det(a)
+ dom.setValue("MatrixResult", str(result))
+ add_history(dom, f"det(A) = {result}")
+ except Exception as e:
+ dom.setValue("MatrixResult", f"错误: {e}")
+
+def atkMatrixEig(dom):
+ try:
+ a = parse_matrix(dom.getValue("MatrixA"))
+ result = np.linalg.eigvals(a)
+ dom.setValue("MatrixResult", str(result))
+ add_history(dom, f"特征值: {result}")
+ except Exception as e:
+ dom.setValue("MatrixResult", f"错误: {e}")
+
+def atkMatrixClear(dom):
+ dom.setValue("MatrixA", ""); dom.setValue("MatrixB", ""); dom.setValue("MatrixResult", "")
+
+# 统计
+def get_stats_data(dom):
+ text = dom.getValue("StatsData")
+ return np.array([float(x) for x in re.split(r"[,\s]+", text.strip()) if x])
+
+def atkStatsMean(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.mean(data)
+ dom.setValue("StatsResult", f"均值: {result}")
+ add_history(dom, f"均值 = {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsStd(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.std(data)
+ dom.setValue("StatsResult", f"标准差: {result}")
+ add_history(dom, f"标准差 = {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsVar(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.var(data)
+ dom.setValue("StatsResult", f"方差: {result}")
+ add_history(dom, f"方差 = {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsMedian(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.median(data)
+ dom.setValue("StatsResult", f"中位数: {result}")
+ add_history(dom, f"中位数 = {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsMin(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.min(data)
+ dom.setValue("StatsResult", f"最小值: {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsMax(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.max(data)
+ dom.setValue("StatsResult", f"最大值: {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsSum(dom):
+ try:
+ data = get_stats_data(dom)
+ result = np.sum(data)
+ dom.setValue("StatsResult", f"求和: {result}")
+ except Exception as e:
+ dom.setValue("StatsResult", f"错误: {e}")
+
+def atkStatsClear(dom):
+ dom.setValue("StatsData", ""); dom.setValue("StatsResult", "")
+
+# 方程求解
+def atkSolveQuadratic(dom):
+ try:
+ a = float(dom.getValue("CoefA") or 0)
+ b = float(dom.getValue("CoefB") or 0)
+ c = float(dom.getValue("CoefC") or 0)
+ if a == 0:
+ dom.setValue("SolverResult", "a不能为0")
+ return
+ delta = b**2 - 4*a*c
+ if delta >= 0:
+ x1 = (-b + math.sqrt(delta)) / (2*a)
+ x2 = (-b - math.sqrt(delta)) / (2*a)
+ result = f"x₁ = {x1:.6f}, x₂ = {x2:.6f}"
+ else:
+ real = -b / (2*a)
+ imag = math.sqrt(-delta) / (2*a)
+ result = f"x₁ = {real:.6f} + {imag:.6f}i, x₂ = {real:.6f} - {imag:.6f}i"
+ dom.setValue("SolverResult", result)
+ add_history(dom, f"{a}x²+{b}x+{c}=0 → {result}")
+ except Exception as e:
+ dom.setValue("SolverResult", f"错误: {e}")
+
+# 记忆功能
+def atkMemoryStoreA(dom):
+ try: state["memory"]["A"] = float(state["display"]); dom.setValue("MemIndicator", "A已存")
+ except: pass
+
+def atkMemoryStoreB(dom):
+ try: state["memory"]["B"] = float(state["display"]); dom.setValue("MemIndicator", "B已存")
+ except: pass
+
+def atkMemoryStoreC(dom):
+ try: state["memory"]["C"] = float(state["display"]); dom.setValue("MemIndicator", "C已存")
+ except: pass
+
+def atkMemoryStoreM(dom):
+ try: state["memory"]["M"] = float(state["display"]); dom.setValue("MemIndicator", "M已存")
+ except: pass
+
+def atkPressShift(dom):
+ state["shift"] = not state["shift"]
+ dom.setValue("ShiftIndicator", "SHIFT" if state["shift"] else " ")
+
+# 启动
+atlastk.launch(globals=globals())
\ No newline at end of file