From e14dc9c909bd0f20116b040fe01859d9d9592c40 Mon Sep 17 00:00:00 2001 From: a-ogilvie Date: Mon, 13 May 2019 20:27:07 +0900 Subject: [PATCH 1/2] chore: install and configure prettier --- .eslintignore | 1 + .eslintrc | 4 ++-- .prettierrc | 6 ++++++ package.json | 5 ++++- yarn.lock | 36 ++++++++++++++++++++++++++++++++++++ 5 files changed, 49 insertions(+), 3 deletions(-) create mode 100644 .eslintignore create mode 100644 .prettierrc diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..a261f29 --- /dev/null +++ b/.eslintignore @@ -0,0 +1 @@ +dist/* diff --git a/.eslintrc b/.eslintrc index bb6e371..62159be 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,7 +1,7 @@ { - "extends": "airbnb-base", + "extends": ["airbnb-base", "plugin:prettier/recommended"], "rules": { "import/prefer-default-export": 0, "no-plusplus": 0 - }, + } } diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..3f53f70 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,6 @@ +{ + "arrowParens": "avoid", + "printWidth": 100, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/package.json b/package.json index 27f715e..421fcb8 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "keywords": [ "regression", "data", - "fiting", + "fitting", "modeling", "analysis" ], @@ -33,9 +33,12 @@ "chai": "^3.5.0", "eslint": "^3.19.0", "eslint-config-airbnb-base": "^11.2.0", + "eslint-config-prettier": "^4.2.0", "eslint-plugin-import": "^2.7.0", + "eslint-plugin-prettier": "^3.1.0", "mocha": "^3.2.0", "nyc": "^11.0.3", + "prettier": "1.17.0", "uglify-js": "3" }, "author": "Tom Alexander " diff --git a/yarn.lock b/yarn.lock index ea17205..84bf257 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1207,6 +1207,13 @@ eslint-config-airbnb-base@^11.2.0: dependencies: eslint-restricted-globals "^0.1.1" +eslint-config-prettier@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-4.2.0.tgz#70b946b629cd0e3e98233fd9ecde4cb9778de96c" + integrity sha512-y0uWc/FRfrHhpPZCYflWC8aE0KRJRY04rdZVfl8cL3sEZmOYyaBdhdlQPjKZBnuRMyLVK+JUZr7HaZFClQiH4w== + dependencies: + get-stdin "^6.0.0" + eslint-import-resolver-node@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz#4422574cde66a9a7b099938ee4d508a199e0e3cc" @@ -1236,6 +1243,13 @@ eslint-plugin-import@^2.7.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" +eslint-plugin-prettier@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.0.tgz#8695188f95daa93b0dc54b249347ca3b79c4686d" + integrity sha512-XWX2yVuwVNLOUhQijAkXz+rMPPoCr7WFiAl8ig6I7Xn+pPVhDhzg4DxHpmbeb0iqjO9UronEA3Tb09ChnFVHHA== + dependencies: + prettier-linter-helpers "^1.0.0" + eslint-restricted-globals@^0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz#35f0d5cbc64c2e3ed62e93b4b1a7af05ba7ed4d7" @@ -1365,6 +1379,11 @@ extsprintf@^1.2.0: version "1.4.0" resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" +fast-diff@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/fast-diff/-/fast-diff-1.2.0.tgz#73ee11982d86caaf7959828d519cfe927fac5f03" + integrity sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w== + fast-levenshtein@~2.0.4: version "2.0.6" resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" @@ -1519,6 +1538,11 @@ get-caller-file@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" +get-stdin@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-6.0.0.tgz#9e09bf712b360ab9225e812048f71fde9c89657b" + integrity sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g== + get-stream@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" @@ -2483,6 +2507,18 @@ preserve@^0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" +prettier-linter-helpers@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz#d23d41fe1375646de2d0104d3454a3008802cf7b" + integrity sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w== + dependencies: + fast-diff "^1.1.2" + +prettier@1.17.0: + version "1.17.0" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.17.0.tgz#53b303676eed22cc14a9f0cec09b477b3026c008" + integrity sha512-sXe5lSt2WQlCbydGETgfm1YBShgOX4HxQkFPvbxkcwgDvGDeqVau8h+12+lmSVlP3rHPz0oavfddSZg/q+Szjw== + private@^0.1.6, private@^0.1.7: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" From a5a32ecc139de2aa5fbb815c109935354bf0253d Mon Sep 17 00:00:00 2001 From: a-ogilvie Date: Mon, 13 May 2019 20:50:44 +0900 Subject: [PATCH 2/2] chore: reformat production code --- dist/regression.js | 58 +++++++++---------- src/regression.js | 120 ++++++++++++++++++++-------------------- test/data.js | 5 -- test/regression.test.js | 6 +- 4 files changed, 92 insertions(+), 97 deletions(-) diff --git a/dist/regression.js b/dist/regression.js index 8c4f866..9aefd8b 100644 --- a/dist/regression.js +++ b/dist/regression.js @@ -57,14 +57,14 @@ var DEFAULT_OPTIONS = { order: 2, precision: 2, period: null }; /** - * Determine the coefficient of determination (r^2) of a fit from the observations - * and predictions. - * - * @param {Array>} data - Pairs of observed x-y values - * @param {Array>} results - Pairs of observed predicted x-y values - * - * @return {number} - The r^2 value, or NaN if one cannot be calculated. - */ + * Determine the coefficient of determination (r^2) of a fit from the observations + * and predictions. + * + * @param {Array>} data - Pairs of observed x-y values + * @param {Array>} results - Pairs of observed predicted x-y values + * + * @return {number} - The r^2 value, or NaN if one cannot be calculated. + */ function determinationCoefficient(data, results) { var predictions = []; var observations = []; @@ -96,14 +96,14 @@ } /** - * Determine the solution of a system of linear equations A * x = b using - * Gaussian elimination. - * - * @param {Array>} input - A 2-d matrix of data in row-major form [ A | b ] - * @param {number} order - How many degrees to solve for - * - * @return {Array} - Vector of normalized solution coefficients matrix (x) - */ + * Determine the solution of a system of linear equations A * x = b using + * Gaussian elimination. + * + * @param {Array>} input - A 2-d matrix of data in row-major form [ A | b ] + * @param {number} order - How many degrees to solve for + * + * @return {Array} - Vector of normalized solution coefficients matrix (x) + */ function gaussianElimination(input, order) { var matrix = input; var n = input.length - 1; @@ -143,25 +143,25 @@ } /** - * Round a number to a precision, specificed in number of decimal places - * - * @param {number} number - The number to round - * @param {number} precision - The number of decimal places to round to: - * > 0 means decimals, < 0 means powers of 10 - * - * - * @return {numbr} - The number, rounded - */ + * Round a number to a precision, specificed in number of decimal places + * + * @param {number} number - The number to round + * @param {number} precision - The number of decimal places to round to: + * > 0 means decimals, < 0 means powers of 10 + * + * + * @return {number} - The number, rounded + */ function round(number, precision) { var factor = Math.pow(10, precision); return Math.round(number * factor) / factor; } /** - * The set of all fitting methods - * - * @namespace - */ + * The set of all fitting methods + * + * @namespace + */ var methods = { linear: function linear(data, options) { var sum = [0, 0, 0, 0, 0]; diff --git a/src/regression.js b/src/regression.js index 1a313f2..1126b8c 100644 --- a/src/regression.js +++ b/src/regression.js @@ -1,14 +1,14 @@ const DEFAULT_OPTIONS = { order: 2, precision: 2, period: null }; /** -* Determine the coefficient of determination (r^2) of a fit from the observations -* and predictions. -* -* @param {Array>} data - Pairs of observed x-y values -* @param {Array>} results - Pairs of observed predicted x-y values -* -* @return {number} - The r^2 value, or NaN if one cannot be calculated. -*/ + * Determine the coefficient of determination (r^2) of a fit from the observations + * and predictions. + * + * @param {Array>} data - Pairs of observed x-y values + * @param {Array>} results - Pairs of observed predicted x-y values + * + * @return {number} - The r^2 value, or NaN if one cannot be calculated. + */ function determinationCoefficient(data, results) { const predictions = []; const observations = []; @@ -25,27 +25,27 @@ function determinationCoefficient(data, results) { const ssyy = observations.reduce((a, observation) => { const difference = observation[1] - mean; - return a + (difference * difference); + return a + difference * difference; }, 0); const sse = observations.reduce((accum, observation, index) => { const prediction = predictions[index]; const residual = observation[1] - prediction[1]; - return accum + (residual * residual); + return accum + residual * residual; }, 0); - return 1 - (sse / ssyy); + return 1 - sse / ssyy; } /** -* Determine the solution of a system of linear equations A * x = b using -* Gaussian elimination. -* -* @param {Array>} input - A 2-d matrix of data in row-major form [ A | b ] -* @param {number} order - How many degrees to solve for -* -* @return {Array} - Vector of normalized solution coefficients matrix (x) -*/ + * Determine the solution of a system of linear equations A * x = b using + * Gaussian elimination. + * + * @param {Array>} input - A 2-d matrix of data in row-major form [ A | b ] + * @param {number} order - How many degrees to solve for + * + * @return {Array} - Vector of normalized solution coefficients matrix (x) + */ function gaussianElimination(input, order) { const matrix = input; const n = input.length - 1; @@ -85,25 +85,25 @@ function gaussianElimination(input, order) { } /** -* Round a number to a precision, specificed in number of decimal places -* -* @param {number} number - The number to round -* @param {number} precision - The number of decimal places to round to: -* > 0 means decimals, < 0 means powers of 10 -* -* -* @return {numbr} - The number, rounded -*/ + * Round a number to a precision, specificed in number of decimal places + * + * @param {number} number - The number to round + * @param {number} precision - The number of decimal places to round to: + * > 0 means decimals, < 0 means powers of 10 + * + * + * @return {number} - The number, rounded + */ function round(number, precision) { const factor = 10 ** precision; return Math.round(number * factor) / factor; } /** -* The set of all fitting methods -* -* @namespace -*/ + * The set of all fitting methods + * + * @namespace + */ const methods = { linear(data, options) { const sum = [0, 0, 0, 0, 0]; @@ -120,15 +120,15 @@ const methods = { } } - const run = ((len * sum[2]) - (sum[0] * sum[0])); - const rise = ((len * sum[3]) - (sum[0] * sum[1])); + const run = len * sum[2] - sum[0] * sum[0]; + const rise = len * sum[3] - sum[0] * sum[1]; const gradient = run === 0 ? 0 : round(rise / run, options.precision); - const intercept = round((sum[1] / len) - ((gradient * sum[0]) / len), options.precision); + const intercept = round(sum[1] / len - (gradient * sum[0]) / len, options.precision); - const predict = x => ([ + const predict = x => [ round(x, options.precision), - round((gradient * x) + intercept, options.precision)] - ); + round(gradient * x + intercept, options.precision), + ]; const points = data.map(point => predict(point[0])); @@ -155,15 +155,15 @@ const methods = { } } - const denominator = ((sum[1] * sum[2]) - (sum[5] * sum[5])); - const a = Math.exp(((sum[2] * sum[3]) - (sum[5] * sum[4])) / denominator); - const b = ((sum[1] * sum[4]) - (sum[5] * sum[3])) / denominator; + const denominator = sum[1] * sum[2] - sum[5] * sum[5]; + const a = Math.exp((sum[2] * sum[3] - sum[5] * sum[4]) / denominator); + const b = (sum[1] * sum[4] - sum[5] * sum[3]) / denominator; const coeffA = round(a, options.precision); const coeffB = round(b, options.precision); - const predict = x => ([ + const predict = x => [ round(x, options.precision), round(coeffA * Math.exp(coeffB * x), options.precision), - ]); + ]; const points = data.map(point => predict(point[0])); @@ -185,18 +185,18 @@ const methods = { sum[0] += Math.log(data[n][0]); sum[1] += data[n][1] * Math.log(data[n][0]); sum[2] += data[n][1]; - sum[3] += (Math.log(data[n][0]) ** 2); + sum[3] += Math.log(data[n][0]) ** 2; } } - const a = ((len * sum[1]) - (sum[2] * sum[0])) / ((len * sum[3]) - (sum[0] * sum[0])); + const a = (len * sum[1] - sum[2] * sum[0]) / (len * sum[3] - sum[0] * sum[0]); const coeffB = round(a, options.precision); - const coeffA = round((sum[2] - (coeffB * sum[0])) / len, options.precision); + const coeffA = round((sum[2] - coeffB * sum[0]) / len, options.precision); - const predict = x => ([ + const predict = x => [ round(x, options.precision), - round(round(coeffA + (coeffB * Math.log(x)), options.precision), options.precision), - ]); + round(round(coeffA + coeffB * Math.log(x), options.precision), options.precision), + ]; const points = data.map(point => predict(point[0])); @@ -218,19 +218,19 @@ const methods = { sum[0] += Math.log(data[n][0]); sum[1] += Math.log(data[n][1]) * Math.log(data[n][0]); sum[2] += Math.log(data[n][1]); - sum[3] += (Math.log(data[n][0]) ** 2); + sum[3] += Math.log(data[n][0]) ** 2; } } - const b = ((len * sum[1]) - (sum[0] * sum[2])) / ((len * sum[3]) - (sum[0] ** 2)); - const a = ((sum[2] - (b * sum[0])) / len); + const b = (len * sum[1] - sum[0] * sum[2]) / (len * sum[3] - sum[0] ** 2); + const a = (sum[2] - b * sum[0]) / len; const coeffA = round(Math.exp(a), options.precision); const coeffB = round(b, options.precision); - const predict = x => ([ + const predict = x => [ round(x, options.precision), - round(round(coeffA * (x ** coeffB), options.precision), options.precision), - ]); + round(round(coeffA * x ** coeffB, options.precision), options.precision), + ]; const points = data.map(point => predict(point[0])); @@ -254,7 +254,7 @@ const methods = { for (let i = 0; i < k; i++) { for (let l = 0; l < len; l++) { if (data[l][1] !== null) { - a += (data[l][0] ** i) * data[l][1]; + a += data[l][0] ** i * data[l][1]; } } @@ -277,13 +277,13 @@ const methods = { const coefficients = gaussianElimination(rhs, k).map(v => round(v, options.precision)); - const predict = x => ([ + const predict = x => [ round(x, options.precision), round( - coefficients.reduce((sum, coeff, power) => sum + (coeff * (x ** power)), 0), - options.precision, + coefficients.reduce((sum, coeff, power) => sum + coeff * x ** power, 0), + options.precision ), - ]); + ]; const points = data.map(point => predict(point[0])); diff --git a/test/data.js b/test/data.js index fcb130a..263c17d 100644 --- a/test/data.js +++ b/test/data.js @@ -1,5 +1,4 @@ export const linear = { - zeroGradient: { r2: NaN, equation: [0, 10], @@ -44,11 +43,9 @@ export const linear = { data: [[10, 21], [100, null], [1000, 2001], [10000, null]], points: [[10, 21], [100, 201], [1000, 2001], [10000, 20001]], }, - }; export const exponential = { - growthGreaterThanZero: { r2: 1, equation: [2, 2], @@ -118,7 +115,6 @@ export const power = { }; export const polynomial = { - positiveLinearGradient: { config: { order: 1 }, r2: 1, @@ -208,5 +204,4 @@ export const polynomial = { data: [[1, 6], [2, 11], [3, 18], [4, 27], [5, 38], [6, 51]], points: [[1, 6], [2, 11], [3, 18], [4, 27], [5, 38], [6, 51]], }, - }; diff --git a/test/regression.test.js b/test/regression.test.js index ccf1803..deaaa17 100644 --- a/test/regression.test.js +++ b/test/regression.test.js @@ -13,13 +13,13 @@ describe('round', () => { }); describe('models', () => { - Object.keys(models).forEach((model) => { + Object.keys(models).forEach(model => { describe(model, () => { - Object.keys(models[model]).forEach((name) => { + Object.keys(models[model]).forEach(name => { const example = models[model][name]; describe(name, () => { it(`correctly predicts ${name}`, () => { - let result = regression[model](example.data, example.config); + const result = regression[model](example.data, example.config); delete result.predict; expect(result).to.deep.equal({ r2: example.r2,