[gnome-calculator/60-split-out-a-backend-library] gcalc: implemented adding terms in polynomial
- From: Daniel Espinosa Ortiz <despinosa src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-calculator/60-split-out-a-backend-library] gcalc: implemented adding terms in polynomial
- Date: Fri, 4 Jan 2019 16:23:47 +0000 (UTC)
commit d07f3eeca8f53bba78e13da5e18219e8273c5c32
Author: Daniel Espinosa Ortiz <esodan gmail com>
Date: Fri Jan 4 10:12:27 2019 -0600
gcalc: implemented adding terms in polynomial
gcalc/gcalc-expression.vala | 3 ++
gcalc/gcalc-gexpression.vala | 3 ++
gcalc/gcalc-gpolynomial.vala | 33 +++++---------------
gcalc/gcalc-gterm.vala | 10 ++++++-
gcalc/gcalc-polynomial.vala | 44 +++++++++++++++++++++++++++
gcalc/gcalc-term.vala | 27 +++++++++++++----
tests/gcalc-solving-basic.vala | 68 ++++++++++++++++++++++++++++++++++++++++++
7 files changed, 156 insertions(+), 32 deletions(-)
---
diff --git a/gcalc/gcalc-expression.vala b/gcalc/gcalc-expression.vala
index 8842a4e8..4e86b3fb 100644
--- a/gcalc/gcalc-expression.vala
+++ b/gcalc/gcalc-expression.vala
@@ -24,3 +24,6 @@ public interface GCalc.Expression : Object {
public abstract Result solve ();
}
+public interface GCalc.ErrorExpression : Object, Expression {
+}
+
diff --git a/gcalc/gcalc-gexpression.vala b/gcalc/gcalc-gexpression.vala
index 23a77d47..aac356d4 100644
--- a/gcalc/gcalc-gexpression.vala
+++ b/gcalc/gcalc-gexpression.vala
@@ -30,3 +30,6 @@ public class GCalc.GExpression : Object, Expression {
}
}
+
+public class GCalc.GErrorExpression : GExpression, ErrorExpression {}
+
diff --git a/gcalc/gcalc-gpolynomial.vala b/gcalc/gcalc-gpolynomial.vala
index cc7abaeb..fa038d81 100644
--- a/gcalc/gcalc-gpolynomial.vala
+++ b/gcalc/gcalc-gpolynomial.vala
@@ -20,32 +20,15 @@
*/
public class GCalc.GPolynomial : GExpression, Polynomial {
public override Result solve () {
- Expression res = null;
- Term current = null;
- foreach (Expression e in expressions) {
- var r = e.solve ();
- if (!r.is_valid) {
- return r;
- }
- if (r.expression is Term) {
- var t = r.expression as Term;
- if (current == null) {
- current = t;
- continue;
- }
- try {
- current = current.sum (t) as Term;
- } catch (GLib.Error err) {
- var nerr = new GErrorResult (err.message);
- return new GResult.with_error ((Expression) new GExpression (), (ErrorResult) nerr) as Result;
- }
- }
- if (r.expression is Constant) {
- res = r.expression;
- break;
- }
+ Result res = null;
+ try {
+ var e = evaluate ();
+ res = new GResult (e) as Result;
+ } catch (GLib.Error err) {
+ var nerr = new GErrorResult (err.message);
+ res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) nerr) as Result;
}
- return new GResult (res) as Result;
+ return res;
}
}
diff --git a/gcalc/gcalc-gterm.vala b/gcalc/gcalc-gterm.vala
index 8f9c53b8..92849ae2 100644
--- a/gcalc/gcalc-gterm.vala
+++ b/gcalc/gcalc-gterm.vala
@@ -26,9 +26,17 @@ public class GCalc.GTerm : GExpression, Term {
res = new GResult (e) as Result;
} catch (GLib.Error err) {
var nerr = new GErrorResult (err.message);
- res = new GResult.with_error ((Expression) new GExpression (), (ErrorResult) nerr) as Result;
+ res = new GResult.with_error ((Expression) new GErrorExpression (), (ErrorResult) nerr) as Result;
}
return res;
}
+ // Expression
+ public override string to_string () {
+ string s = "";
+ foreach (Expression e in expressions) {
+ s += e.to_string ();
+ }
+ return s;
+ }
}
diff --git a/gcalc/gcalc-polynomial.vala b/gcalc/gcalc-polynomial.vala
index e8efae06..e00e5c7d 100644
--- a/gcalc/gcalc-polynomial.vala
+++ b/gcalc/gcalc-polynomial.vala
@@ -19,5 +19,49 @@
* Daniel Espinosa <esodan gmail com>
*/
public interface GCalc.Polynomial : Object, Expression {
+ public virtual Expression evaluate () throws GLib.Error {
+ Term current = null;
+ Expression res = null;
+ message ("Terms: %u", expressions.get_n_items ());
+ for (uint i = 0; i < expressions.get_n_items (); i++) {
+ var e = expressions.get_item (i) as Term;
+ if (e == null) {
+ message ("No Term: %s", e.get_type ().name ());
+ continue;
+ }
+ if (current == null) {
+ current = (Term) e;
+ if (i+1 < expressions.get_n_items ()) {
+ continue;
+ }
+ var er = ((Term) e).evaluate ();
+ if (res == null) {
+ res = er;
+ break;
+ }
+ if (res is Constant && er is Constant) {
+ message ("Adding: %s + %s", res.to_string (), er.to_string ());
+ res = ((Constant) res).add ((Constant) er);
+ break;
+ }
+ }
+ var re = current.add ((Term) e);
+ current = null;
+ message ("Current Terms Sum: %s", re.to_string ());
+ if (res == null) {
+ res = re;
+ } else if (res is Constant && re is Constant) {
+ message ("Adding: %s + %s", res.to_string (), re.to_string ());
+ res = ((Constant) res).add ((Constant) re);
+ }
+ if (res != null) {
+ message ("Current Sum: %s", res.to_string ());
+ }
+ }
+ if (res == null) {
+ return new GErrorExpression ();
+ }
+ return res;
+ }
}
diff --git a/gcalc/gcalc-term.vala b/gcalc/gcalc-term.vala
index 985af4ef..9d604317 100644
--- a/gcalc/gcalc-term.vala
+++ b/gcalc/gcalc-term.vala
@@ -19,13 +19,20 @@
* Daniel Espinosa <esodan gmail com>
*/
public interface GCalc.Term : Object, Expression {
- public virtual Expression sum (Term t) throws GLib.Error {
+ public virtual Expression add (Term t) throws GLib.Error {
if (t.expressions.get_n_items () == 0) {
- return this;
+ return new GConstant.@double (1.0);
}
- return this;
+ Expression res = new GExpression ();
+ var e = evaluate ();
+ var e2 = t.evaluate ();
+ if (e is Constant && e2 is Constant) {
+ res = ((Constant) e).add ((Constant) e2);
+ }
+ return res;
}
public virtual Expression evaluate () throws GLib.Error {
+ message ("Evaluating term: %s", this.to_string ());
Expression current = null;
Operator current_operator = null;
bool first = true;
@@ -35,18 +42,22 @@ public interface GCalc.Term : Object, Expression {
throw new TermError.INVALID_OPERATOR ("Incorrect position for operator in expression");
}
if (e is Minus && first) {
- var c = new GConstant.@double (1.0);
- c = c.neg () as GConstant;
+ var c = new GConstant.@double (-1.0);
current = c;
first = false;
}
+ message ("Setting current operator to: %s", e.get_type ().name());
current_operator = e as Operator;
+ continue;
} else if (e is Constant) {
if (current == null) {
current = e;
first = false;
} else if (current is Constant) {
if (current_operator != null) {
+ if (current_operator is Minus) {
+ current = (current as Constant).multiply (e as Constant);
+ }
if (current_operator is Multiply) {
current = (current as Constant).multiply (e as Constant);
}
@@ -57,11 +68,15 @@ public interface GCalc.Term : Object, Expression {
}
}
}
+ if (current == null) {
+ throw new TermError.EVALUATION_FAIL ("Evaluation fail on Term");
+ }
return current;
}
}
public errordomain GCalc.TermError {
- INVALID_OPERATOR
+ INVALID_OPERATOR,
+ EVALUATION_FAIL
}
diff --git a/tests/gcalc-solving-basic.vala b/tests/gcalc-solving-basic.vala
index c67ad6d9..85ab7f14 100644
--- a/tests/gcalc-solving-basic.vala
+++ b/tests/gcalc-solving-basic.vala
@@ -177,6 +177,74 @@ class Tests {
warning ("Error: %s", e.message);
}
});
+ Test.add_func ("/gcalc/solve/term/add/constant",
+ ()=>{
+ try {
+ var parser = new Parser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("1+1", eqman);
+ assert (eqman.equations.get_n_items () == 1);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ var e = eq.expressions.get_item (0) as Polynomial;
+ assert (e != null);
+ var t1 = e.expressions.get_item (0) as Term;
+ var t2 = e.expressions.get_item (1) as Term;
+ var res = t1.add (t2);
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == 2.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/add/constant-multiple",
+ ()=>{
+ try {
+ var parser = new Parser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("1+1-9+8-3", eqman);
+ assert (eqman.equations.get_n_items () == 1);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ var e = eq.expressions.get_item (0) as Polynomial;
+ assert (e != null);
+ var res = e.evaluate ();
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == -2.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
+ Test.add_func ("/gcalc/solve/term/add-mult-div/constant-multiple",
+ ()=>{
+ try {
+ var parser = new Parser ();
+ var eqman = new GMathEquationManager ();
+ parser.parse ("15/3+18/6-27/9+4*2-3*2", eqman);
+ assert (eqman.equations.get_n_items () == 1);
+ var eq = eqman.equations.get_item (0) as MathEquation;
+ assert (eq != null);
+ var e = eq.expressions.get_item (0) as Polynomial;
+ assert (e != null);
+ var res = e.evaluate ();
+ assert (res != null);
+ message (res.get_type ().name ());
+ var c = res as Constant;
+ assert (c != null);
+ message (c.to_string ());
+ assert (c.real () == 7.0);
+ } catch (GLib.Error e) {
+ warning ("Error: %s", e.message);
+ }
+ });
return Test.run ();
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]