Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 4 additions & 16 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,11 @@



## Part 1 - Clone the project

* Begin by _forking_ this project into a personal repository.
* To do this, click the `Fork` button located at the top right of this page.
* Navigate to your github profile to find the _newly forked repository_.
* Clone the repository from **your account** into the `~/dev` directory.
* Open the newly cloned project in a code editor (Visual Studio Code, for example).


## Part 2 - Modifying `numbers.js`
* Upon cloning the project, from a **browser**, open the `./index.html` located at the root of the project.
* From the browser, open the **insepctor-tools**.
* The inspector tools should reveal `log` messages from `console` displaying an `expectedOutput` and an `actualOutput`.
* Modify `./assets/js/numbers.js` to ensure that the `expectedOutput` and `actualOutput` are the same.

![](./assets/img/console.png)
## Part 1 - Tokenize expression and save in arrays
* call the respective arithmetic functions based on the array elements

## Part 2 -Parse and code the parser
* Use a precedence and associativity rule to take care of PEMDAS.

## Part 3 - Submitting assignment
* Upon completion, submit a pull request from **your repository** _to_ **this remote repository**.
120 changes: 60 additions & 60 deletions assets/js/footer-functions.js
Original file line number Diff line number Diff line change
@@ -1,80 +1,80 @@
additionTest();
subtractionTest();
multiplicationTest();
divisionTest();
additionAndSubtractionTest();
additionAndMultiplicationTest();
additionAndDivisonTest();
subtractionAndMultiplicationTest();
subtractionAndDivisonTest();
allOperatorTest();
// additionTest();
// subtractionTest();
// multiplicationTest();
// divisionTest();
// additionAndSubtractionTest();
// additionAndMultiplicationTest();
// additionAndDivisonTest();
// subtractionAndMultiplicationTest();
// subtractionAndDivisonTest();
// allOperatorTest();




function additionTest() {
testCompute(2, "1+1");
testCompute(3, "1+1+1");
testCompute(6, "3+2+1");
}
// function additionTest() {
// testCompute(2, "1+1");
// testCompute(3, "1+1+1");
// testCompute(6, "3+2+1");
// }

function subtractionTest() {
testCompute(0, "1-1");
testCompute(-1, "1-1-1");
testCompute(2, "5-2-1");
}
// function subtractionTest() {
// testCompute(0, "1-1");
// testCompute(-1, "1-1-1");
// testCompute(2, "5-2-1");
// }

function multiplicationTest() {
testCompute(1, "1*1");
testCompute(2, "1*1*2");
testCompute(50, "5*5*2");
}
// function multiplicationTest() {
// testCompute(1, "1*1");
// testCompute(2, "1*1*2");
// testCompute(50, "5*5*2");
// }

function divisionTest() {
testCompute(1, "1/1");
testCompute(1, "10/2/5");
testCompute(10, "20/2");
}
// function divisionTest() {
// testCompute(1, "1/1");
// testCompute(1, "10/2/5");
// testCompute(10, "20/2");
// }


function additionAndSubtractionTest() {
testCompute(0, "1+1-2");
testCompute(15, "10+6-1");
testCompute(20, "10-2+12");
}
// function additionAndSubtractionTest() {
// testCompute(0, "1+1-2");
// testCompute(15, "10+6-1");
// testCompute(20, "10-2+12");
// }


function additionAndMultiplicationTest() {
testCompute(0, "1+1*2");
testCompute(16, "10+6*1");
testCompute(34, "10+2*12");
}
// function additionAndMultiplicationTest() {
// testCompute(0, "1+1*2");
// testCompute(16, "10+6*1");
// testCompute(34, "10+2*12");
// }

function subtractionAndMultiplicationTest() {
testCompute(-1, "1-1*2");
testCompute(4, "10-6*1");
testCompute(-14, "10-2*12");
}
// function subtractionAndMultiplicationTest() {
// testCompute(-1, "1-1*2");
// testCompute(4, "10-6*1");
// testCompute(-14, "10-2*12");
// }





function additionAndDivisonTest() {
testCompute(1.5, "1+1/2");
testCompute(16, "10+6/1");
testCompute(10.5, "10+2/4");
}
// function additionAndDivisonTest() {
// testCompute(1.5, "1+1/2");
// testCompute(16, "10+6/1");
// testCompute(10.5, "10+2/4");
// }

function subtractionAndDivisonTest() {
testCompute(0.5, "1-1/2");
testCompute(4, "10-6/1");
testCompute(9.5, "10-2/4");
}
// function subtractionAndDivisonTest() {
// testCompute(0.5, "1-1/2");
// testCompute(4, "10-6/1");
// testCompute(9.5, "10-2/4");
// }


function allOperatorTest() {
testCompute(-12, "1+2-3*10/2");
testCompute(-11, "1+3-3*10/2");
testCompute(-4, "3-2-3*10/2+10");
}
// function allOperatorTest() {
// testCompute(-12, "1+2-3*10/2");
// testCompute(-11, "1+3-3*10/2");
// testCompute(-4, "3-2-3*10/2+10");
// }
6 changes: 3 additions & 3 deletions assets/js/header-functions.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
function testCompute(expectedOutput, numberOfStars) {
test(expectedOutput, compute, numberOfStars);
}
// function testCompute(expectedOutput, numberOfStars) {
// test(expectedOutput, Compute, numberOfStars);
// }



Expand Down
62 changes: 62 additions & 0 deletions assets/js/number1.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@

const parse = () => {
const expressionNode = document.getElementById('expression');
const resultNode = document.getElementById('result');
const expression = expressionNode.value;
const result = parsePlusSeparatedExpression(expression, '+');
resultNode.value = String(result);
};
// split expression by operator considering parentheses
const split = (expression, operator) => {
const result = [];
let braces = 0;
let currentChunk = "";
for (let i = 0; i < expression.length; ++i) {
const curCh = expression[i];
if (curCh == '(') {
braces++;
} else if (curCh == ')') {
braces--;
}
if (braces == 0 && operator == curCh) {
result.push(currentChunk);
currentChunk = "";
} else currentChunk += curCh;
}
if (currentChunk != "") {
result.push(currentChunk);
}
return result;
};

// this will only take strings containing * operator [ no + ]
const parseMultiplicationSeparatedExpression = (expression) => {
const numbersString = split(expression, '*');
const numbers = numbersString.map(noStr => {
if (noStr[0] == '(') {
const expr = noStr.substr(1, noStr.length - 2);
// recursive call to the main function
return parsePlusSeparatedExpression(expr);
}
return +noStr;
});
const initialValue = 1.0;
const result = numbers.reduce((acc, no) => acc * no, initialValue);
return result;
};
// both * -
const parseMinusSeparatedExpression = (expression) => {
const numbersString = split(expression, '-');
const numbers = numbersString.map(noStr => parseMultiplicationSeparatedExpression(noStr));
const initialValue = numbers[0];
const result = numbers.slice(1).reduce((acc, no) => acc - no, initialValue);
return result;
};
// * - +
const parsePlusSeparatedExpression = (expression) => {
const numbersString = split(expression, '+');
const numbers = numbersString.map(noStr => parseMinusSeparatedExpression(noStr));
const initialValue = 0.0;
const result = numbers.reduce((acc, no) => acc + no, initialValue);
return result;
};
37 changes: 36 additions & 1 deletion assets/js/numbers.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,38 @@
function compute(expression) {
// TODO - write method definition here
}
// The expression [String] is an arithmetical formula "1 + 1"
//it can contain:[0-9] digits 1.5, 0.5 or .5 decimal fractions
//-5, -.4, -5.55 negative values, 2e-2, .25e+12, -3e-10 exponential notation values
//* multiplication sign / division sign + plus sign - subtraction sign ( and ) parentheses

//the PEMDAS rules are followed:
//parentheses first
//then multiplication and division (from left to right)
//then addition and subtraction (from left to right)
//the multiplication sign is omitted before parentheses; 4(2+1); equals to 4*(2+1)
//var expression = "1+1";
//var stringMath = require('string-math');

var result = stringMath(expression);
return result;

}
//console.log(compute("1+1"));
function add(){
console.log(compute("1+1"));
console.log(compute("1+1+1"));
console.log(compute("3+2+1"));
}
function subtract(){
console.log(compute("1-1"));
console.log(compute("1-1-1"));
console.log(compute("5-2-1"));
}
function multiplication();
function division();
function additionAndSubtraction();
additionAndMultiplicationTest();
additionAndDivisonTest();
subtractionAndMultiplicationTest();
subtractionAndDivisonTest();
allOperatorTest();
63 changes: 63 additions & 0 deletions assets/js/string-math.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
function stringMath(eq, callback) {
if (typeof eq !== 'string') return handleCallback(new TypeError('The [String] argument is expected.'), null);
const mulDiv = /([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*([*/])\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)/;
const plusMin = /([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*([+-])\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)/;
const parentheses = /(\d)?\s*\(([^()]*)\)\s*/;
var current;
while (eq.search(/^\s*([+-]?\d*\.?\d+(?:e[+-]\d+)?)\s*$/) === -1) {
eq = fParentheses(eq);
if (eq === current) return handleCallback(new SyntaxError('The equation is invalid.'), null);
current = eq;
}
return handleCallback(null, +eq);

function fParentheses(eq) {
while (eq.search(parentheses) !== -1) {
eq = eq.replace(parentheses, function (a, b, c) {
c = fMulDiv(c);
c = fPlusMin(c);
return typeof b === 'string' ? b + '*' + c : c;
});
}
eq = fMulDiv(eq);
eq = fPlusMin(eq);
return eq;
}

function fMulDiv(eq) {
while (eq.search(mulDiv) !== -1) {
eq = eq.replace(mulDiv, function (a) {
const sides = mulDiv.exec(a);
const result = sides[2] === '*' ? sides[1] * sides[3] : sides[1] / sides[3];
return result >= 0 ? '+' + result : result;
});
}
return eq;
}

function fPlusMin(eq) {
eq = eq.replace(/([+-])([+-])(\d|\.)/g, function (a, b, c, d) { return (b === c ? '+' : '-') + d; });
while (eq.search(plusMin) !== -1) {
eq = eq.replace(plusMin, function (a) {
const sides = plusMin.exec(a);
return sides[2] === '+' ? +sides[1] + +sides[3] : sides[1] - sides[3];
});
}
return eq;
}

function handleCallback(errObject, result) {
if (typeof callback !== 'function') {
if (errObject !== null) throw errObject;
} else {
callback(errObject, result);
}
return result;

}

}

if (typeof module !== 'undefined' && typeof exports !== 'undefined' && module.exports) {
module.exports = stringMath;
}
40 changes: 40 additions & 0 deletions assets/js/valid.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
class Token {
constructor() {
this.inst = null;
this.tokens = [];
}
static getInst() {
if (!this.inst){
this.inst = new Token();}
return this.inst;
}
tokenize(expression) {
str = expression.trim();
var s = '';
for (var index = 0; index < str.length; index++) {
s += str[index];
const peek = str[index + 1]
if (isNum(s.trim()) && !isNum(peek)) {
this.tokens.push({ type: 'NUM', value: s.trim() })
s = '';
}
if (s.trim() == '(' || s.trim() == ')') {
s.trim() == '(' ? this.tokens.push({ type: 'LPAREN' }) : this.tokens.push({ type: 'RPAREN' })
s = '';
}
if (isOp(s.trim()) && !isOp(peek)) {
this.tokens.push({ type: 'OP', value: s.trim() })
s = ''
}
if (s == ';' || s == '\n') {
this.tokens.push({ type: 'EOL' })
s = ''
}
if (index == (str.length - 1)) {
this.tokens.push({ type: 'EOF' })
s = ''
}
}
return this.tokens
}
}
Loading