From 6d1c3d545061e0747d0feed3396071ec7090a2fb Mon Sep 17 00:00:00 2001 From: Ad5001 Date: Sun, 10 Jan 2021 20:48:11 +0100 Subject: [PATCH] Integrals, opening directly from the command line --- qml/js/mathlib.js | 19 ++++++++++++++----- qml/js/objects.js | 2 +- qml/js/utils.js | 12 ++++++++++++ run.py | 14 ++++++++++++-- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/qml/js/mathlib.js b/qml/js/mathlib.js index 2495c88..d40aa9a 100644 --- a/qml/js/mathlib.js +++ b/qml/js/mathlib.js @@ -21,9 +21,7 @@ .import "expr-eval.js" as ExprEval .import "utils.js" as Utils -const parser = new ExprEval.Parser() -var u = {1: 1, 2: 2, 3: 3} var evalVariables = { // Variables not provided by expr-eval.js, needs to be provided manualy "pi": Math.PI, @@ -35,6 +33,15 @@ var evalVariables = { // Variables not provided by expr-eval.js, needs to be pro "E": Math.E } +var currentVars = {} + +const parser = new ExprEval.Parser() +parser.functions.integral = function(a, b, f, variable) { + // https://en.wikipedia.org/wiki/Simpson%27s_rule + f = parser.parse(f).toJSFunction(variable, currentVars) + return (b-a)/6*(f(a)+4*f((a+b)/2)+f(b)) +} + class Expression { constructor(expr) { this.expr = expr @@ -49,7 +56,8 @@ class Expression { execute(x = 1) { if(this.cached) return this.cachedValue - return this.calc.evaluate(Object.assign({'x': x}, evalVariables)) + currentVars = Object.assign({'x': x}, evalVariables) + return this.calc.evaluate(currentVars) } simplify(x) { @@ -111,9 +119,10 @@ class Sequence extends Expression { cache(n = 1) { var str = Utils.simplifyExpression(this.calc.substitute('n', n-this.valuePlus).toString()) var expr = parser.parse(str).simplify() - var l = {} + var l = {'n': n-this.valuePlus} // Just in case, add n (for custom functions) l[this.name] = this.calcValues - this.calcValues[n] = expr.evaluate(Object.assign(l, evalVariables)) + currentVars = Object.assign(l, evalVariables) + this.calcValues[n] = expr.evaluate(currentVars) } toString(forceSign=false) { diff --git a/qml/js/objects.js b/qml/js/objects.js index 3ca5965..5d45b2f 100644 --- a/qml/js/objects.js +++ b/qml/js/objects.js @@ -236,7 +236,7 @@ class Function extends ExecutableObject { if(this.displayMode == 'application') { return `${this.name}: ${this.definitionDomain} ⸺> ${this.destinationDomain}\n ${' '.repeat(this.name.length)}x ⸺> ${this.expression.toString()}` } else { - return `${this.name}(x) = ${this.expression.toString()}\nD${this.name} = ${this.definitionDomain}` + return `${this.name}(x) = ${this.expression.toString()}\nD${Utils.textsub(this.name)} = ${this.definitionDomain}` } } diff --git a/qml/js/utils.js b/qml/js/utils.js index 989c6f4..d5891c8 100644 --- a/qml/js/utils.js +++ b/qml/js/utils.js @@ -23,6 +23,8 @@ var powerpos = { "+": "⁺", "=": "⁼", " ": " ", + "(": "⁽", + ")": "⁾", "0": "⁰", "1": "¹", "2": "²", @@ -64,6 +66,8 @@ var indicepos = { "-": "₋", "+": "₊", "=": "₌", + "(": "₍", + ")": "₎", " ": " ", "0": "₀", "1": "₁", @@ -255,6 +259,14 @@ function makeExpressionReadable(str) { [/(\d|\))×/g, '$1'], //[/×(\d|\()/g, '$1'], [/\(([^)(+.\/-]+)\)/g, "$1"], + [/integral\((.+), ?(.+), ("|')(.+)("|'), ?("|')(.+)("|')\)/g, function(match, a, b, p1, body, p2, p3, by, p4) { + console.log('Intégrale', a, b, body, by) + if(a.length < b.length) { + return `∫${textsub(a)}${textsup(b)} ${body} d${by}` + } else { + return `∫${textsup(b)}${textsub(a)} ${body} d${by}` + } + }] ] str = simplifyExpression(str) diff --git a/run.py b/run.py index a89ea0f..59552bf 100644 --- a/run.py +++ b/run.py @@ -25,7 +25,11 @@ import os import tempfile from platform import release as os_release from json import dumps -from sys import platform +from sys import platform, argv + +pwd = os.getcwd() +os.chdir(os.path.dirname(os.path.realpath(__file__))) + tempfile = tempfile.mkstemp(suffix = '.png')[1] @@ -77,7 +81,7 @@ class Helper(QObject): # TODO: Better copy system os.system("xclip -selection clipboard -t image/png -i " + tempfile) -app = QApplication([]) +app = QApplication(argv) app.setApplicationName("Logarithmic Plotter") app.setOrganizationName("Ad5001") app.setWindowIcon(QIcon(os.path.realpath(os.path.join(os.getcwd(), "logplotter.svg")))) @@ -88,6 +92,12 @@ engine.rootContext().setContextProperty("Helper", helper) engine.addImportPath(os.path.realpath(os.path.join(os.getcwd(), "qml"))) engine.load(os.path.realpath(os.path.join(os.getcwd(), "qml", "LogGraph.qml"))) +os.chdir(pwd) +if len(argv) > 0 and os.path.exists(argv[-1]) and argv[-1].split('.')[-1] == 'json': + print(argv[-1]) + engine.rootObjects()[0].loadDiagram(argv[-1]) +os.chdir(os.path.dirname(os.path.realpath(__file__))) + if not engine.rootObjects(): print("No root object") exit(-1)