about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--.idea/vcs.xml6
-rw-r--r--Discovery.md2
-rw-r--r--README.md2
-rw-r--r--app.py44
-rw-r--r--templates/index.html163
5 files changed, 188 insertions, 29 deletions
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 0000000..94a25f7
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$" vcs="Git" />
+  </component>
+</project>
\ No newline at end of file
diff --git a/Discovery.md b/Discovery.md
index 7d3c460..42be246 100644
--- a/Discovery.md
+++ b/Discovery.md
@@ -7,6 +7,6 @@ git: <https://github.com/mounderfod/pyMathEngine>
 
 A mathematical engine in the style of Wolfram Alpha.
 Very useful for homework, assignments, etc.
-Currently, the engine can only take univariate expressions, but additional features are being added over time.
+Currently, the engine can only take univariate expressions and simple equations, but additional features are being added over time.
 
 [(view screenshot)](https://cdn.discordapp.com/attachments/838048982873538572/1131593838285295637/image.png)
\ No newline at end of file
diff --git a/README.md b/README.md
index e699297..a1a1cb5 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,6 @@
 
 A mathematical engine in the style of Wolfram Alpha.
 Very useful for homework, assignments, etc.
-Currently, the engine can only take univariate expressions, but additional features are being added over time.
+Currently, the engine can only take univariate expressions and simple equations, but additional features are being added over time.
 
 ![(A screenshot of the app)](https://cdn.discordapp.com/attachments/838048982873538572/1131593838285295637/image.png)
\ No newline at end of file
diff --git a/app.py b/app.py
index 51b158b..09b4c5c 100644
--- a/app.py
+++ b/app.py
@@ -1,7 +1,8 @@
 import base64
 import os
 
-from sympy import diff, integrate, print_latex, latex, pretty, solve, Eq
+import flask
+from sympy import diff, integrate, print_latex, latex, pretty, solve, Eq, nsolve, limit, oo, solveset
 from sympy.parsing.sympy_parser import *
 from sympy.plotting import plot
 from io import BytesIO
@@ -15,6 +16,31 @@ app = Flask(__name__)
 def hello_world():  # put application's code here
     return render_template("index.html", HOSTNAME=os.getenv("DETA_SPACE_APP_HOSTNAME"))
 
+@app.route('/api/equation')
+def equation():
+    args = request.args
+
+    try:
+        lhs = parse_expr(args['lhs'], transformations=standard_transformations + (split_symbols, implicit_multiplication, function_exponentiation, convert_xor))
+        rhs = parse_expr(args['rhs'], transformations=standard_transformations + (split_symbols, implicit_multiplication, function_exponentiation, convert_xor))
+
+        response = {'solution': []}
+
+        eq = Eq(lhs, rhs)
+        try:
+            for i in eq.atoms(Symbol):
+                response['solution'].append(latex(i) + "=" + latex(solveset(eq, i)))
+        except NotImplementedError:
+            response['solution'] = "\\text{Solution could not be calculated.}"
+
+        response = flask.jsonify(response)
+        response.headers.add('Access-Control-Allow-Origin', '*')
+        return response
+
+    except Exception as e:
+        print(e)
+        return f"Bad Request", 400
+
 @app.route('/api/univariate')
 def plotter():
     args = request.args
@@ -29,15 +55,25 @@ def plotter():
         p._backend.process_series()
         p._backend.fig.savefig(buf, format="png")
 
+        try:
+            solution = [latex(i) for i in solveset(Eq(exp, 0))]
+        except NotImplementedError:
+            solution = "\\text{Solution could not be calculated.}"
+
         data = base64.b64encode(buf.getbuffer()).decode("ascii")
-        return {
+        response = flask.jsonify({
             "variable": pretty(exp.atoms(Symbol).pop()),
             "expression": latex(exp),
             "plot": data,
             "diff": latex(diff(exp)),
             "integral": latex(integrate(exp)),
-            "solution": [latex(i) for i in solve(Eq(exp, 0))]
-        }
+            "limit_inf": latex(limit(exp, pretty(exp.atoms(Symbol).pop()), oo)),
+            "limit_zero": latex(limit(exp, pretty(exp.atoms(Symbol).pop()), 0)),
+            "solution": solution
+        })
+        response.headers.add('Access-Control-Allow-Origin', '*')
+        return response
+
     except Exception as e:
         print(e)
         return f"Bad Request", 400
diff --git a/templates/index.html b/templates/index.html
index e87e7e4..4d44706 100644
--- a/templates/index.html
+++ b/templates/index.html
@@ -30,40 +30,142 @@
       <div class="alert alert-info mb-2" role="alert">
         Welcome to <b>pyMathEngine</b>, a mathematical engine in the style of
         Wolfram Alpha. <br />
-        Currently the engine can only take univariate expressions (e.g. \(
-        x^2+2x+3 \)), but additional features are being added over time.<br />
+        Currently, the engine can only take univariate expressions and simple
+        equations, but additional features are being added over time. , but
+        additional features are being added over time.<br />
         Some notes:
         <ul>
           <li>Euler's number (\(e\)) is written as "E" in the box</li>
           <li>Pi (\(\pi\)) is written as "pi" in the box</li>
         </ul>
       </div>
-      <div class="input-group mb-3">
-        <input
-          id="expression"
-          type="text"
-          class="form-control"
-          placeholder="Enter a univariate expression..."
-          aria-label="Enter a univariate expression..."
-          aria-describedby="button-addon"
-        />
-        <button
-          class="btn btn-secondary"
-          type="button"
-          onclick="get()"
-          id="button-addon"
-        >
-          Search
-        </button>
+      <div class="row mt-3">
+        <div class="col-sm">
+          <div class="input-group mb-3">
+            <input
+              id="expression"
+              type="text"
+              class="form-control"
+              placeholder="Enter a univariate expression..."
+              aria-label="Enter a univariate expression..."
+              aria-describedby="button-addon"
+            />
+            <button
+              class="btn btn-secondary"
+              type="button"
+              onclick="get_uni()"
+              id="button-addon"
+            >
+              Search
+            </button>
+          </div>
+        </div>
+        <div class="col-sm">
+          <div class="input-group mb-3">
+            <input
+              id="lhs"
+              type="text"
+              placeholder="LHS of equation"
+              class="form-control"
+            />
+            <span class="input-group-text">=</span>
+            <input
+              id="rhs"
+              type="text"
+              placeholder="RHS of equation"
+              class="form-control"
+            />
+            <button
+              class="btn btn-secondary"
+              type="button"
+              onclick="get_eq()"
+              id="button-addon"
+            >
+              Search
+            </button>
+          </div>
+        </div>
       </div>
     </div>
-    <div id="response" class="m-5"></div>
+    <div id="response" class="m-3"></div>
   </body>
   <script>
-    function get() {
+    function get_eq() {
+      let lhs = document.getElementById("lhs").value;
+      let rhs = document.getElementById("rhs").value;
+      let responseBox = document.getElementById("response");
+      responseBox.innerHTML = `
+      <div class="d-flex justify-content-center">
+        <div class="spinner-border" role="status">
+          <span class="visually-hidden">Loading...</span>
+        </div>
+      </div>
+      `;
+
+      fetch(
+        `http://${"{{ HOSTNAME }}"}/api/equation?lhs=${encodeURIComponent(
+          lhs
+        )}&rhs=${encodeURIComponent(rhs)}`
+      )
+        .then((response) => {
+          if (!response.ok) {
+            let err = new Error("HTTP error: " + response.status);
+            err.response = response;
+            err.status = response.status;
+            throw err;
+          } else {
+            response.json().then((data) => {
+              console.log(data);
+              let responseBox = document.getElementById("response");
+
+              if (data.solution.length == 0) {
+                solution = "\\text{No solutions exist}";
+              } else {
+                solution = data.solution;
+              }
+
+              responseBox.innerHTML = "";
+              responseBox.innerHTML += `
+              <div class="card mt-2">
+                <div class="card-header">Solutions</div>
+                <div class="card-body overflow-auto"><p>
+                    $$ ${solution} $$
+                    </p></div>
+              </div>
+              `;
+
+              MathJax.typeset();
+            });
+          }
+        })
+        .catch((err) => {
+          let responseBox = document.getElementById("response");
+
+          responseBox.innerHTML = "";
+          responseBox.innerHTML += `
+          <div class="card mt-2">
+            <div class="card-header bg-danger text-white">Error</div>
+            <div class="card-body">
+                <p>${err.message}</p>
+                <p>This is likely because you have entered an invalid expression.</p>
+            </div>
+          </div>
+          `;
+        });
+    }
+
+    function get_uni() {
       let exp = document.getElementById("expression").value;
+      let responseBox = document.getElementById("response");
+      responseBox.innerHTML = `
+      <div class="d-flex justify-content-center">
+        <div class="spinner-border" role="status">
+          <span class="visually-hidden">Loading...</span>
+        </div>
+      </div>
+      `;
       fetch(
-        `https://${"{{ HOSTNAME }}"}/api/univariate?func=${encodeURIComponent(
+        `http://${"{{ HOSTNAME }}"}/api/univariate?func=${encodeURIComponent(
           exp
         )}`
       )
@@ -78,6 +180,11 @@
             response.json().then((data) => {
               console.log(data);
               let responseBox = document.getElementById("response");
+              if (data.solution.length == 0) {
+                solution = "\\text{No solutions exist}";
+              } else {
+                solution = data.solution;
+              }
               responseBox.innerHTML = "";
               responseBox.innerHTML += `
               <div class="card mt-2">
@@ -90,7 +197,7 @@
               <div class="card mt-2">
                 <div class="card-header">Solutions (where \\(f(${data.variable}) = 0\\))</div>
                 <div class="card-body overflow-auto"><p>
-                    $$ ${data.solution} $$ 
+                    $$ ${solution} $$
                     </p></div>
               </div>
 
@@ -115,6 +222,16 @@
                 </div>
               </div>
 
+              <div class="card mt-2">
+                <div class="card-header">Limits</div>
+                <div class="card-body">
+                    <p>$$ \\lim_{${data.variable} \\rightarrow  \\infty} = ${data.limit_inf}$$</p>
+                    <p>$$ \\lim_{${data.variable} \\rightarrow  0} = ${data.limit_zero}$$</p>
+                </div>
+              </div>
+
+
+
               `;
               MathJax.typeset();
             });