average-rating
Advanced tools
Comparing version 1.1.12 to 1.2.0
{ | ||
"extends": "eslint-config-ggc" | ||
"extends": "eslint-config-goes" | ||
} |
@@ -5,3 +5,5 @@ /** | ||
**/ | ||
exports = module.exports = require('./src/main'); | ||
exports.version = require('./package').version; | ||
const main = require('./src/main'); | ||
main.version = require('./package').version; | ||
module.exports = main; |
{ | ||
"version": "1.1.12", | ||
"version": "1.2.0", | ||
"name": "average-rating", | ||
@@ -13,22 +13,14 @@ "description": "Calculate average score and rating based on Wilson Score Equation", | ||
"engines": { | ||
"node": ">= 6.0" | ||
"node": ">= 8.6" | ||
}, | ||
"scripts": { | ||
"lint": "eslint .", | ||
"snyk": "snyk test", | ||
"tape": "nyc tape test/start.js | tap-spec", | ||
"report": "nyc report --reporter=lcov", | ||
"pretest": "npm run lint && npm run snyk", | ||
"test": "npm run tape", | ||
"posttest": "npm run report", | ||
"coveralls": "npm test && cat ./coverage/lcov.info | coveralls" | ||
"lint": "eslint src test/specs", | ||
"pretest": "npm run lint", | ||
"test": "tap test/start.js --coverage --reporter=spec", | ||
"reset": "node reset" | ||
}, | ||
"devDependencies": { | ||
"coveralls": "latest", | ||
"eslint": "latest", | ||
"eslint-config-ggc": "latest", | ||
"nyc": "latest", | ||
"snyk": "latest", | ||
"tap-spec": "latest", | ||
"tape": "latest" | ||
"coveralls": "^3.0.9", | ||
"eslint-config-goes": "^1.1.8", | ||
"tap": "^14.10.2" | ||
}, | ||
@@ -35,0 +27,0 @@ "keywords": [ |
@@ -7,6 +7,4 @@ # average-rating | ||
[![Coverage Status](https://coveralls.io/repos/github/ndaidong/average-rating/badge.svg?branch=master)](https://coveralls.io/github/ndaidong/average-rating?branch=master) | ||
[![Dependency Status](https://gemnasium.com/badges/github.com/ndaidong/average-rating.svg)](https://gemnasium.com/github.com/ndaidong/average-rating) | ||
[![Known Vulnerabilities](https://snyk.io/test/npm/average-rating/badge.svg)](https://snyk.io/test/npm/average-rating) | ||
![Google app on Google Play](http://i.imgur.com/NgQX5OW.png) | ||
![Google app on Google Play](https://i.imgur.com/XKEEpdb.png) | ||
@@ -16,11 +14,8 @@ ## Usage | ||
``` | ||
var av = require('average-rating'); | ||
var rate = av.rate; | ||
var average = av.average; | ||
var score = av.score; | ||
const { | ||
score, | ||
rate, | ||
average | ||
} = require('average-rating'); | ||
// from 1 to 5 stars | ||
let rating = [134055, 57472, 143135, 365957, 1448459]; | ||
rate(rating); // --> 0.84 | ||
average(rating); // --> 4.4 | ||
@@ -31,2 +26,9 @@ // get Winson score for a pair of (Positive, Negative) voting | ||
score(1000, 1000); // --> 0.48 | ||
// from 1 to 5 stars | ||
const rating = [134055, 57472, 143135, 365957, 1448459]; | ||
rate(rating); // --> 0.84 | ||
// calculate average | ||
average(rating); // --> 4.4 | ||
``` | ||
@@ -48,2 +50,15 @@ | ||
##### Update | ||
- Since v1.1.5, this `rate` method accepts custom range of ratings. 5 or more values are OK. | ||
``` | ||
const input = [3, 4, 2, 6, 12, 46, 134, 213, 116, 91, 45, 15, 58, 96, 1654]; // 15 values | ||
rate(input); // => 0.85 | ||
rate([3, 4, 2, 6, 12, 46, 134, 213, 116, 91]); // => 0.74 | ||
``` | ||
### .average(Array ratings) | ||
@@ -50,0 +65,0 @@ |
@@ -7,43 +7,52 @@ /** | ||
var getWilsonScore = (p, n) => { | ||
const score = (p, n) => { | ||
if (p === 0 && n === 0) { | ||
return 0; | ||
} | ||
let r = ((p + 1.9208) / (p + n) - 1.96 * Math.sqrt(p * n / (p + n) + 0.9604) / (p + n)) / (1 + 3.8416 / (p + n)); | ||
return r.toFixed(2); | ||
const r = ((p + 1.9208) / (p + n) - 1.96 * Math.sqrt(p * n / (p + n) + 0.9604) / (p + n)) / (1 + 3.8416 / (p + n)); | ||
return Number(r.toFixed(2)); | ||
}; | ||
module.exports = { | ||
score: getWilsonScore, | ||
rate: (rating) => { | ||
let n = 0; | ||
let p = 0; | ||
n += rating[0]; | ||
n += rating[1] * 0.75; | ||
p += rating[1] * 0.25; | ||
n += rating[2] * 0.5; | ||
p += rating[2] * 0.5; | ||
n += rating[3] * 0.25; | ||
p += rating[3] * 0.75; | ||
p += rating[4]; | ||
const rate = (rating) => { | ||
const size = rating.length; | ||
return getWilsonScore(p, n); | ||
}, | ||
average: (rating) => { | ||
let total = rating.reduce((prev, current) => { | ||
return prev + current; | ||
}); | ||
if (total === 0) { | ||
return 0; | ||
} | ||
let sum = 0; | ||
let k = 1; | ||
rating.forEach((item) => { | ||
sum += item * k; | ||
k++; | ||
}); | ||
let r = sum / total; | ||
return r.toFixed(1); | ||
let n = rating[0]; | ||
let p = rating[size - 1]; | ||
const step = (1 / (size - 1)).toFixed(2); | ||
const totalStep = size - 1; | ||
for (let i = 1; i < totalStep; i++) { | ||
const ep = (step * i).toFixed(2); | ||
p += rating[i] * ep; | ||
n += rating[totalStep - i] * ep; | ||
} | ||
return score(p, n); | ||
}; | ||
const average = (rating) => { | ||
const total = rating.reduce((prev, current) => { | ||
return prev + current; | ||
}, 0); | ||
if (total === 0) { | ||
return 0; | ||
} | ||
let sum = 0; | ||
let k = 1; | ||
rating.forEach((item) => { | ||
sum += item * k; | ||
k++; | ||
}); | ||
const r = sum / total; | ||
return Number(r.toFixed(1)); | ||
}; | ||
module.exports = { | ||
score, | ||
rate, | ||
average, | ||
}; |
@@ -6,15 +6,14 @@ /** | ||
var test = require('tape'); | ||
const test = require('tap').test; | ||
var AverageRating = require('../../../index'); | ||
const AverageRating = require('../../../index'); | ||
var samples = require('../samples'); | ||
const samples = require('../samples'); | ||
test('Testing "average" method', (assert) => { | ||
samples.forEach((sample) => { | ||
let rating = sample.rating; | ||
let expect = sample.expect.average; | ||
let actual = Number(AverageRating.average(rating)); | ||
let s = rating.join(', '); | ||
const rating = sample.rating; | ||
const expect = sample.expect.average; | ||
const actual = Number(AverageRating.average(rating)); | ||
const s = rating.join(', '); | ||
assert.deepEqual(actual, expect, `.average([${s}]) should be ${expect}`); | ||
@@ -21,0 +20,0 @@ }); |
@@ -6,16 +6,15 @@ /** | ||
var test = require('tape'); | ||
const test = require('tap').test; | ||
var AverageRating = require('../../../index'); | ||
const AverageRating = require('../../../index'); | ||
var samples = require('../samples'); | ||
const samples = require('../samples'); | ||
test('Testing "rate" method', (assert) => { | ||
samples.forEach((sample) => { | ||
let rating = sample.rating; | ||
let expect = sample.expect.score; | ||
let actual = Number(AverageRating.rate(rating)); | ||
let s = rating.join(', '); | ||
assert.deepEqual(actual, expect, `.rage([${s}]) should be ${expect}`); | ||
const rating = sample.rating; | ||
const expect = sample.expect.score; | ||
const actual = Number(AverageRating.rate(rating)); | ||
const s = rating.join(', '); | ||
assert.deepEqual(actual, expect, `.rate([${s}]) should be ${expect}`); | ||
}); | ||
@@ -25,1 +24,39 @@ | ||
}); | ||
test('Testing "rate" with custom range', (assert) => { | ||
const data = [ | ||
{ | ||
input: [3, 4, 2, 6, 12, 46, 134, 213, 116, 91, 45, 15, 58, 96, 1654], | ||
expect: 0.85, | ||
}, | ||
{ | ||
input: [3, 4, 2, 6, 12, 46, 134, 213, 116, 91], | ||
expect: 0.74, | ||
}, | ||
{ | ||
input: [1311, 655, 1008, 1847, 4685, 13522, 31570, 34238, 18180, 11029], | ||
expect: 0.72, | ||
}, | ||
{ | ||
input: [125, 166, 17, 290, 400, 310], | ||
expect: 0.62, | ||
}, | ||
{ | ||
input: [125, 166, 17, 290, 400, 310, 1800], | ||
expect: 0.79, | ||
}, | ||
]; | ||
data.map((sample) => { | ||
const { | ||
input, | ||
expect, | ||
} = sample; | ||
const actual = AverageRating.rate(input); | ||
const params = input.join(', '); | ||
assert.deepEqual(actual, expect, `.rate([${params}]) should be ${expect}`); | ||
return actual; | ||
}); | ||
assert.end(); | ||
}); |
@@ -1,2 +0,2 @@ | ||
var samples = [ | ||
const samples = [ | ||
{ | ||
@@ -6,4 +6,4 @@ rating: [0, 0, 0, 0, 0], | ||
average: 0, | ||
score: 0 | ||
} | ||
score: 0, | ||
}, | ||
}, { | ||
@@ -13,4 +13,4 @@ rating: [1, 1, 1, 1, 1], | ||
average: 3.0, | ||
score: 0.17 | ||
} | ||
score: 0.17, | ||
}, | ||
}, { | ||
@@ -20,4 +20,4 @@ rating: [2, 2, 2, 2, 2], | ||
average: 3.0, | ||
score: 0.24 | ||
} | ||
score: 0.24, | ||
}, | ||
}, { | ||
@@ -27,4 +27,4 @@ rating: [3, 3, 3, 3, 3], | ||
average: 3.0, | ||
score: 0.27 | ||
} | ||
score: 0.27, | ||
}, | ||
}, { | ||
@@ -34,4 +34,4 @@ rating: [4, 4, 4, 4, 4], | ||
average: 3.0, | ||
score: 0.3 | ||
} | ||
score: 0.3, | ||
}, | ||
}, { | ||
@@ -41,4 +41,4 @@ rating: [5, 5, 5, 5, 5], | ||
average: 3.0, | ||
score: 0.32 | ||
} | ||
score: 0.32, | ||
}, | ||
}, { | ||
@@ -48,4 +48,4 @@ rating: [5, 4, 3, 2, 1], | ||
average: 2.3, | ||
score: 0.15 | ||
} | ||
score: 0.15, | ||
}, | ||
}, { | ||
@@ -55,4 +55,4 @@ rating: [5, 0, 0, 0, 5], | ||
average: 3.0, | ||
score: 0.24 | ||
} | ||
score: 0.24, | ||
}, | ||
}, { | ||
@@ -62,4 +62,4 @@ rating: [5, 0, 0, 4, 5], | ||
average: 3.3, | ||
score: 0.33 | ||
} | ||
score: 0.33, | ||
}, | ||
}, { | ||
@@ -69,4 +69,4 @@ rating: [5, 4, 0, 0, 5], | ||
average: 2.7, | ||
score: 0.21 | ||
} | ||
score: 0.21, | ||
}, | ||
}, { | ||
@@ -76,4 +76,4 @@ rating: [0, 0, 0, 0, 5], | ||
average: 5, | ||
score: 0.57 | ||
} | ||
score: 0.57, | ||
}, | ||
}, { | ||
@@ -83,4 +83,4 @@ rating: [0, 0, 0, 4, 5], | ||
average: 4.6, | ||
score: 0.56 | ||
} | ||
score: 0.56, | ||
}, | ||
}, { | ||
@@ -90,4 +90,4 @@ rating: [0, 0, 3, 4, 5], | ||
average: 4.2, | ||
score: 0.51 | ||
} | ||
score: 0.51, | ||
}, | ||
}, { | ||
@@ -97,4 +97,4 @@ rating: [0, 2, 3, 4, 5], | ||
average: 3.9, | ||
score: 0.45 | ||
} | ||
score: 0.45, | ||
}, | ||
}, { | ||
@@ -104,4 +104,4 @@ rating: [1, 2, 3, 4, 5], | ||
average: 3.7, | ||
score: 0.42 | ||
} | ||
score: 0.42, | ||
}, | ||
}, { | ||
@@ -111,4 +111,4 @@ rating: [9524, 4158, 10177, 25971, 68669], | ||
average: 4.2, | ||
score: 0.79 | ||
} | ||
score: 0.79, | ||
}, | ||
}, { | ||
@@ -118,7 +118,7 @@ rating: [134055, 57472, 143135, 365957, 1448459], | ||
average: 4.4, | ||
score: 0.84 | ||
} | ||
} | ||
score: 0.84, | ||
}, | ||
}, | ||
]; | ||
module.exports = samples; |
@@ -6,83 +6,81 @@ /** | ||
var test = require('tape'); | ||
const test = require('tap').test; | ||
var AverageRating = require('../../../index'); | ||
const AverageRating = require('../../../index'); | ||
let samples = [ | ||
const samples = [ | ||
{ | ||
p: 0, | ||
n: 1, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
p: 0, | ||
n: 5, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
p: 0, | ||
n: 10, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
p: 0, | ||
n: 20, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
p: 0, | ||
n: 100, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
p: 0, | ||
n: 1000, | ||
e: 0 | ||
e: 0, | ||
}, { | ||
n: 0, | ||
p: 1, | ||
e: 0.21 | ||
e: 0.21, | ||
}, { | ||
n: 0, | ||
p: 5, | ||
e: 0.57 | ||
e: 0.57, | ||
}, { | ||
n: 0, | ||
p: 10, | ||
e: 0.72 | ||
e: 0.72, | ||
}, { | ||
n: 0, | ||
p: 20, | ||
e: 0.84 | ||
e: 0.84, | ||
}, { | ||
n: 0, | ||
p: 100, | ||
e: 0.96 | ||
e: 0.96, | ||
}, { | ||
n: 0, | ||
p: 1000, | ||
e: 1 | ||
e: 1, | ||
}, { | ||
n: 1, | ||
p: 1, | ||
e: 0.09 | ||
e: 0.09, | ||
}, { | ||
n: 5, | ||
p: 5, | ||
e: 0.24 | ||
e: 0.24, | ||
}, { | ||
n: 500, | ||
p: 500, | ||
e: 0.47 | ||
e: 0.47, | ||
}, { | ||
n: 1000, | ||
p: 1000, | ||
e: 0.48 | ||
} | ||
e: 0.48, | ||
}, | ||
]; | ||
test('Testing "score" method', (assert) => { | ||
samples.forEach((sample) => { | ||
let expect = sample.e; | ||
let actual = Number(AverageRating.score(sample.p, sample.n)); | ||
const expect = sample.e; | ||
const actual = Number(AverageRating.score(sample.p, sample.n)); | ||
assert.deepEqual(actual, expect, `.score(${sample.p}, ${sample.n}) should be ${expect}`); | ||
}); | ||
assert.end(); | ||
}); |
@@ -1,4 +0,1 @@ | ||
var fs = require('fs'); | ||
var path = require('path'); | ||
/** | ||
@@ -8,9 +5,19 @@ * Import specs | ||
var dirs = ['average', 'rate', 'score']; | ||
const { | ||
existsSync, | ||
readdirSync, | ||
} = require('fs'); | ||
const { | ||
extname, | ||
join, | ||
} = require('path'); | ||
const dirs = ['average', 'rate', 'score']; | ||
dirs.forEach((dir) => { | ||
let where = './test/specs/' + dir; | ||
if (fs.existsSync(where)) { | ||
fs.readdirSync(where).forEach((file) => { | ||
if (path.extname(file) === '.js') { | ||
require(path.join('.' + where, file)); | ||
const where = './test/specs/' + dir; | ||
if (existsSync(where)) { | ||
readdirSync(where).forEach((file) => { | ||
if (extname(file) === '.js') { | ||
require(join('.' + where, file)); | ||
} | ||
@@ -17,0 +24,0 @@ }); |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
11319
3
15
360
80
3
2