diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 00000000..f58eb0d3 --- /dev/null +++ b/.flowconfig @@ -0,0 +1,9 @@ +[ignore] +.*/test/.* +.*/scripts/.* + +[include] + +[libs] + +[options] diff --git a/README.md b/README.md index 4e4af18c..d42d1dc5 100644 --- a/README.md +++ b/README.md @@ -1,74 +1,62 @@ -## A step by step solver for math +# Mathsteps +[![Join the chat at https://gitter.im/mathsteps-chat/Lobby](https://badges.gitter.im/mathsteps-chat/Lobby.svg)](https://gitter.im/mathsteps-chat/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![Build Status](https://travis-ci.org/socraticorg/mathsteps.svg?branch=master)](https://travis-ci.org/socraticorg/mathsteps) -[![Join the chat at https://gitter.im/mathsteps-chat/Lobby](https://badges.gitter.im/mathsteps-chat/Lobby.svg)](https://gitter.im/mathsteps-chat/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Build Status](https://travis-ci.org/socraticorg/mathsteps.svg?branch=master)](https://travis-ci.org/socraticorg/mathsteps) +Mathsteps is a step-by-step math solver. It helps in solving equations, simplifying an expression and factoring a polynomial. (more to come 😄) -https://www.youtube.com/watch?v=iCrargw1rrM +**Solve an equation** -## Requirements - -Mathsteps requires Node version > 6.0.0 - -## Usage +```javascript +const steps = mathsteps.solveEquation('2x + 3x = 35'); +``` -To install mathsteps using npm: +**See all the change types** +```javascript +const changes = mathsteps.ChangeTypes; +``` +Learn [how to use mathsteps](https://github.com/socraticorg/mathsteps/wiki/How-to-use-mathsteps) and [how the codebase works](https://github.com/socraticorg/mathsteps/wiki/Mathsteps-organization). - npm install mathsteps +## Examples +Here is an example to get you started. -```js +```javascript const mathsteps = require('mathsteps'); const steps = mathsteps.simplifyExpression('2x + 2x + x + x'); steps.forEach(step => { - console.log("before change: " + step.oldNode); // before change: 2 x + 2 x + x + x - console.log("change: " + step.changeType); // change: ADD_POLYNOMIAL_TERMS - console.log("after change: " + step.newNode); // after change: 6 x - console.log("# of substeps: " + step.substeps.length); // # of substeps: 3 + console.log("before change: " + step.oldNode); + console.log("change: " + step.changeType); + console.log("after change: " + step.newNode); + console.log("no of substeps: " + step.substeps.length); }); -``` - -To solve an equation: -```js -const steps = mathsteps.solveEquation('2x + 3x = 35'); -steps.forEach(step => { - console.log("before change: " + step.oldEquation.print()); // e.g. before change: 2x + 3x = 35 - console.log("change: " + step.changeType); // e.g. change: SIMPLIFY_LEFT_SIDE - console.log("after change: " + step.newEquation.print()); // e.g. after change: 5x = 35 - console.log("# of substeps: " + step.substeps.length); // e.g. # of substeps: 2 -}); +/* +before change: 2 x + 2 x + x + x +change: ADD_POLYNOMIAL_TERMS +after change: 6 x +no of substeps: 3 +*/ ``` +In this example we have an equation `2x + 2x + x + x` that is being simplified by the method `simplifyExpression`. It returns the output which tells about the equation before and after applying the change, what change was applied and the no of substeps. -To see all the change types: -```js -const changes = mathsteps.ChangeTypes; +## Installation +Mathsteps is available as the `mathsteps` package on [npm](https://www.npmjs.com/package/mathsteps). +``` +npm install mathsteps --save ``` - - ## Contributing +The main objective of the mathsteps is to continue to evolve and provide more operations and features. Read below to learn how can you contribute to the project. -Hi! If you're interested in working on this, that would be super awesome! -Learn more here: [CONTRIBUTING.md](CONTRIBUTING.md). - -## Build - -First clone the project from github: - - git clone https://github.com/socraticorg/mathsteps.git - cd mathsteps +**Contributing guide** -Install the project dependencies: - - npm install +Read our [contributing guide](CONTRIBUTING.md) to suggest more features, report bugs or contribute code. ## Test +``` +npm test +``` -To execute tests for the library, install the project dependencies once: - - npm install - -Then, the tests can be executed: +## License +Apache-2.0 - npm test diff --git a/lib/node/Creator.js b/lib/node/Creator.js index 165a6863..c6878ccc 100644 --- a/lib/node/Creator.js +++ b/lib/node/Creator.js @@ -1,14 +1,22 @@ +// @flow + /* Functions to generate any mathJS node supported by the stepper see http://mathjs.org/docs/expressions/expression_trees.html#nodes for more information on nodes in mathJS */ +type value = string | number; + +type baseNode = { + [property: string]: value +} + const math = require('mathjs'); const NodeType = require('./Type'); const NodeCreator = { - operator (op, args, implicit=false) { + operator (op: string, args: Array, implicit: boolean=false) { switch (op) { case '+': return new math.expression.node.OperatorNode('+', 'add', args); @@ -28,27 +36,27 @@ const NodeCreator = { // In almost all cases, use Negative.negate (with naive = true) to add a // unary minus to your node, rather than calling this constructor directly - unaryMinus (content) { + unaryMinus (content: Array) { return new math.expression.node.OperatorNode( '-', 'unaryMinus', [content]); }, - constant (val) { + constant (val: number) { return new math.expression.node.ConstantNode(val); }, - symbol (name) { + symbol (name: string) { return new math.expression.node.SymbolNode(name); }, - parenthesis (content) { + parenthesis (content: baseNode) { return new math.expression.node.ParenthesisNode(content); }, // exponent might be null, which means there's no exponent node. // similarly, coefficient might be null, which means there's no coefficient // the symbol node can never be null. - polynomialTerm (symbol, exponent, coeff, explicitCoeff=false) { + polynomialTerm (symbol: baseNode, exponent: baseNode, coeff: Object, explicitCoeff: boolean=false) { let polyTerm = symbol; if (exponent) { polyTerm = this.operator('^', [polyTerm, exponent]); @@ -68,7 +76,7 @@ const NodeCreator = { }, // Given a root value and a radicand (what is under the radical) - nthRoot (radicandNode, rootNode) { + nthRoot (radicandNode: baseNode, rootNode: baseNode) { const symbol = NodeCreator.symbol('nthRoot'); return new math.expression.node.FunctionNode(symbol, [radicandNode, rootNode]); } diff --git a/package.json b/package.json index 4bd61c77..e84d71b5 100644 --- a/package.json +++ b/package.json @@ -13,10 +13,12 @@ "eslint": "^3.10.2", "eslint-config-google": "^0.7.0", "eslint-plugin-sort-requires": "^2.1.0", + "flow-bin": "^0.43.1", "mocha": "2.4.5" }, "scripts": { "lint": "node_modules/.bin/eslint .", + "flow": "flow", "test": "node_modules/.bin/mocha --recursive", "setup-hooks": "ln -s ../../scripts/git-hooks/pre-commit.sh .git/hooks/pre-commit" },