Skip to content
This repository has been archived by the owner on May 23, 2019. It is now read-only.

Commit

Permalink
Fix problems with all existing tests
Browse files Browse the repository at this point in the history
TODO: Add tests for rational logic
  • Loading branch information
IsaMorphic committed Apr 23, 2019
1 parent d6dd9e8 commit 9f19724
Show file tree
Hide file tree
Showing 7 changed files with 44 additions and 56 deletions.
7 changes: 5 additions & 2 deletions src/equations.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ Equation.prototype._crossMultiply = function() {
// Both sides should now be rationals and we are ready to cross-multiply
this.lhs = newLhs.numer.multiply(newRhs.denom);
this.rhs = newLhs.denom.multiply(newRhs.numer);
}
};

Equation.prototype.solveFor = function(variable) {
this._crossMultiply();
Expand Down Expand Up @@ -162,6 +162,9 @@ Equation.prototype.solveFor = function(variable) {
var c = coefs.c;
var d = coefs.d;

if (a == undefined)
throw new Error("No Solution");

// Calculate D and D0.
var D = a.multiply(b).multiply(c).multiply(d).multiply(18);
D = D.subtract(b.pow(3).multiply(d).multiply(4));
Expand Down Expand Up @@ -314,7 +317,7 @@ Equation.prototype._maxDegreeOfVariable = function(variable) {
};

Equation.prototype._variableCanBeIsolated = function(variable) {
return this._maxDegreeOfVariable(variable) === 1;
return this._maxDegreeOfVariable(variable) === 1 && this._noCrossProductsWithVariable(variable);
};

Equation.prototype._noCrossProductsWithVariable = function(variable) {
Expand Down
55 changes: 28 additions & 27 deletions src/expressions.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ var Expression = function(variable) {
var t = new Term(v);
this.terms = [t];
} else if (isInt(variable)) {
var f = new Fraction(variable, 1)
var f = new Fraction(variable, 1);
var t = new Term(f);
this.terms = [t];
} else if (variable instanceof Fraction) {
Expand All @@ -37,7 +37,7 @@ Expression.prototype.coefficients = function() {
arr.push(this.terms[i].coefficient());
}
return arr;
}
};

Expression.prototype.simplify = function() {
var copy = this.copy();
Expand Down Expand Up @@ -133,7 +133,7 @@ Expression.prototype.divide = function(a, simplify) {
var copy = this.copy();

for (var i = 0; i < copy.terms.length; i++) {
copy.terms[i] = copy.terms[i].divide(thatTerm);
copy.terms[i] = copy.terms[i].divide(thatTerm, simplify);
}

return copy;
Expand All @@ -143,15 +143,9 @@ Expression.prototype.divide = function(a, simplify) {
return new Expression(rational);
}
} else if (a instanceof Fraction || isInt(a)) {
var copy = this.copy();

for (var i = 0; i < copy.terms.length; i++) {
copy.terms[i] = copy.terms[i].divide(a);
}

return copy;
return this.divide(new Expression(a), simplify);
} else {
throw new TypeError("Invalid Argument (" + a.toString() + "): Divisor must be of type Fraction or Integer.");
throw new TypeError("Invalid Argument (" + a.toString() + "): Divisor must be of type Expression, Fraction or Integer.");
}
};

Expand All @@ -177,7 +171,6 @@ Expression.prototype.pow = function(a, simplify) {

Expression.prototype.eval = function(values, simplify) {
var exp = new Expression();
exp.constants = (simplify ? [this.constant()] : this.constants.slice());

//add all evaluated terms of this to exp
exp = this.terms.reduce(function(p, c) { return p.add(c.eval(values, simplify), simplify); }, exp);
Expand All @@ -201,7 +194,7 @@ Expression.prototype.toRational = function() {
var numer = copy;
var denom = new Expression(1);
return new Rational(numer, denom);
}
};

Expression.prototype.toString = function(options) {
var str = "";
Expand Down Expand Up @@ -493,9 +486,9 @@ Term.prototype.subtract = function(term) {
var copy = this.copy();
copy.coefficients = [copy.coefficient().subtract(term.coefficient())];
return copy;
} else if (a instanceof Rational) {
} else if (term instanceof Rational) {
var exp = new Expression(this);
return exp.toRational().subtract(a);
return exp.toRational().subtract(term);
} else {
throw new TypeError("Invalid Argument (" + term.toString() + "): Subtrahend must be of type String, Expression, Term, Fraction or Integer.");
}
Expand All @@ -506,7 +499,13 @@ Term.prototype.multiply = function(a, simplify) {

if (a instanceof Term) {
thisTerm.variables = thisTerm.variables.concat(a.variables);
thisTerm.coefficients = a.coefficients.concat(thisTerm.coefficients);
thisTerm.coefficients = a.coefficients
.concat(thisTerm.coefficients)
.filter(function(a) {
return !(a.numer == 1 && a.denom == 1);
});
if (thisTerm.coefficients.length == 0)
thisTerm.coefficients.push(new Fraction(1, 1));

} else if (isInt(a) || a instanceof Fraction) {
var newCoef = (isInt(a) ? new Fraction(a, 1) : a);
Expand Down Expand Up @@ -619,13 +618,15 @@ Term.prototype.maxDegreeOfVariable = function(variable) {
};

Term.prototype.canBeCombinedWith = function(term) {
if (term instanceof Rational)
if (term instanceof Rational ||
(this.maxDegree() == 0 &&
term.maxDegree() == 0))
return true;
var thisVars = this.variables;
var thatVars = term.variables;

if (thisVars.length != thatVars.length) {
return this.maxDegree() == 0 && term.maxDegree() == 0;
return false;
}

var matches = 0;
Expand Down Expand Up @@ -762,7 +763,7 @@ var Rational = function(a, b) {
this.denom = b;
else
this.denom = new Expression(b);
}
};

function toFraction(a) {
var i;
Expand Down Expand Up @@ -797,11 +798,11 @@ function gcd_term(a, b) {

Rational.prototype.copy = function() {
return new Rational(this.numer.copy(), this.denom.copy());
}
};

Rational.prototype.canBeCombinedWith = function(a) {
return true;
}
};

Rational.prototype.add = function(a) {
if (a instanceof Rational) {
Expand All @@ -818,7 +819,7 @@ Rational.prototype.add = function(a) {
} else {
return this.add(new Expression(a));
}
}
};

Rational.prototype.subtract = function(a) {
if (a instanceof Rational) {
Expand All @@ -828,7 +829,7 @@ Rational.prototype.subtract = function(a) {
} else {
return this.subtract(new Expression(a));
}
}
};

Rational.prototype.multiply = function(a) {
if (a instanceof Rational) {
Expand All @@ -842,7 +843,7 @@ Rational.prototype.multiply = function(a) {
} else {
return this.multiply(new Expression(a));
}
}
};

Rational.prototype.divide = function(a) {
if (a instanceof Rational) {
Expand All @@ -856,7 +857,7 @@ Rational.prototype.divide = function(a) {
} else {
return this.divide(new Expression(a));
}
}
};

Rational.prototype.reduce = function() {
var copy = this.copy();
Expand All @@ -878,11 +879,11 @@ Rational.prototype.reduce = function() {
copy.denom = copy.denom.divide(g);

return copy;
}
};

Rational.prototype.toString = function() {
return "(" + this.numer + ") / (" + this.denom + ")";
}
};

module.exports = {
Rational: Rational,
Expand Down
4 changes: 2 additions & 2 deletions src/parser.js
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ Parser.prototype.parseTermRest = function(factor) {
} else if (this.match('divide')) {
this.update();
var devfactor = this.parseFactor();
return factor.divide(this.parseTermRest(devfactor));
return this.parseTermRest(factor.divide(devfactor));
} else if (this.match('epsilon')) {
return factor;
} else {
Expand All @@ -176,7 +176,7 @@ Parser.prototype.parseTermRest = function(factor) {
* Is used to convert expressions to fractions, as dividing by expressions is not possible
**/
Parser.prototype.convertToFraction = function(expression) {
if (expression.terms.filter(function(term) { return term.maxDegree() > 0 }).length > 0) {
if (expression.terms.filter(function(term) { return term.maxDegree() > 0; }).length > 0) {
throw new TypeError('Invalid Argument (' + expression.toString() + '): Divisor must be of type Integer or Fraction.');
} else {
var c = expression.constant();
Expand Down
5 changes: 3 additions & 2 deletions test/equation-spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
var Expression = require('../src/expressions').Expression;
var Rational = require('../src/expressions').Rational;
var Equation = require('../src/equations');
var Fraction = require('../src/fractions');
var round = require('../src/helper').round;
Expand Down Expand Up @@ -26,9 +27,9 @@ describe("A linear equation with one variable", function() {
expect(algebra.toTex(eq)).toEqual("\\frac{1}{5}x + \\frac{4}{5} = x - \\frac{1}{6}");
});

it("should return a fraction when solving for the one variable", function() {
it("should return a Rational when solving for the one variable", function() {
var answer = eq.solveFor("x");
expect(answer instanceof Fraction).toBe(true);
expect(answer instanceof Expression).toBe(true);
});

it("should throw an exception when solving for a variable that isn't there", function() {
Expand Down
14 changes: 1 addition & 13 deletions test/expression-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -357,18 +357,6 @@ describe("Expression division", function() {
expect(x.divide(y).toString()).toEqual("xy^-1");
});

it("should not allow division of a multinominal denomenator", function() {
var multi = new Expression("x").add(3);

expect(function(){x.divide(multi);}).toThrow("Invalid Argument ((x)/(x + 3)): Only monomial expressions can be divided.");
});

it("should not allow division of a multinominal numenator", function() {
var multi = new Expression("x").add(3);

expect(function(){multi.divide(x);}).toThrow("Invalid Argument ((x + 3)/(x)): Only monomial expressions can be divided.");
});

it("should throw an exception if dividing by zero", function() {
expect(function(){x.divide(0);}).toThrow("Divide By Zero");
});
Expand Down Expand Up @@ -683,7 +671,7 @@ describe("Expression evaluation with unsimplified expressions", function() {
it("works when there's multiple coefficients", function() {
var exp = new Expression("x").multiply(5).multiply(4, false); // 4 * 5x
var answer = exp.eval({x:2}, false);
expect(answer.toString()).toEqual("4 * 5 * 2");
expect(answer.toString()).toEqual("2 * 5 * 4");

});

Expand Down
7 changes: 1 addition & 6 deletions test/parser-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@ var Parser = require("../src/parser.js"),
describe("Input validity", function() {
var p = new Parser();

it("should throw an error if the input contains invalid divisions.", function(){
var input = "1/(x-3)=1";
expect(function(){p.parse(input);}).toThrow(new Error("Invalid Argument (x - 3): Divisor must be of type Integer or Fraction."));
});

it("does not accept special characters", function(){
var input = "2+4*x-€";
expect(function(){p.parse(input);}).toThrow(new Error("Token error at character € at position 6"));
Expand Down Expand Up @@ -101,7 +96,7 @@ describe("Operators", function() {
expect(p.parse(input).toString()).toEqual(new Equation(lhs,rhs).toString());
});

it("should parse / correctly", function(){
it("should parse / correctly", function() {
var input = "x/2 = 8";
var lhs = new Expression("x").divide(2);
var rhs = new Expression(8);
Expand Down
8 changes: 4 additions & 4 deletions test/term-spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ describe("Term evaluation", function() {

var e = t.eval({x:2}, false);

expect(e.toString()).toEqual("5 * 3 * 2");
expect(e.toString()).toEqual("2 * 3 * 5");
});

it("should work when there is more than 1 coefficient and more than 1 variable and simplify = false", function() {
Expand All @@ -255,7 +255,7 @@ describe("Term evaluation", function() {
t = t.multiply(6, false); // 6 * 5 * 3xy

var answer = t.eval({x:2}, false); // 6 * 5 * 3 * 2y
expect(answer.toString()).toEqual("6 * 5 * 3 * 2y");
expect(answer.toString()).toEqual("2 * 3 * 5 * 6y");
});

it("works with negative numbers", function() {
Expand All @@ -269,9 +269,9 @@ describe("Term evaluation", function() {

t = t.multiply(6, false); // 6 * 5 * 3xy

var answer = t.eval({x:-2}, false); // 6 * 5 * 3 * -2y
var answer = t.eval({x:-2}, true); // 6 * 5 * 3 * -2y

expect(answer.toString()).toEqual("6 * 5 * 3 * -2y");
expect(answer.toString()).toEqual("-180y");
});
});

Expand Down

0 comments on commit 9f19724

Please sign in to comment.