!1 Integrate developments for version 0.1.0
* development: #9 Prepare publish #9 Add licence #9 Prepare publish - add README #10 Error in new test 20x9 #8 Improve result test of election - add display matrix job #8 Improve result test of election - add display matrix job Implement addVotes #9 Prepare publish Update results_data.json (Jose de la Mancha - Test 20x9) #8 Improve result test of election Update .gitlab-ci.yml Update .gitlab-ci.yml Update .gitlab-ci.yml #7 Add build task to transpil
Showing
12 changed files
with
297 additions
and
11 deletions
... | @@ -6,9 +6,22 @@ cache: | ... | @@ -6,9 +6,22 @@ cache: |
6 | 6 | ||
7 | stages: | 7 | stages: |
8 | - test | 8 | - test |
9 | - build | ||
9 | 10 | ||
10 | node_test: | 11 | node_test: |
11 | stage: test | 12 | stage: test |
12 | script: | 13 | script: |
13 | - npm install | 14 | - npm install |
14 | - npm test | 15 | - npm test |
16 | |||
17 | display_details: | ||
18 | stage: test | ||
19 | when: manual | ||
20 | script: | ||
21 | - node tests/node/displayResults.js | ||
22 | |||
23 | build: | ||
24 | stage: build | ||
25 | script: | ||
26 | - npm install | ||
27 | - npm run build | ... | ... |
.npmignore
0 → 100644
LICENCE
0 → 100644
1 | The MIT License (MIT) | ||
2 | |||
3 | Copyright (c) 2016 Vincent Peybernes | ||
4 | |||
5 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
6 | of this software and associated documentation files (the "Software"), to deal | ||
7 | in the Software without restriction, including without limitation the rights | ||
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
9 | copies of the Software, and to permit persons to whom the Software is | ||
10 | furnished to do so, subject to the following conditions: | ||
11 | |||
12 | The above copyright notice and this permission notice shall be included in all | ||
13 | copies or substantial portions of the Software. | ||
14 | |||
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
21 | SOFTWARE. |
README.md
0 → 100644
1 | # RelativePlacementJS | ||
2 | [![build status](http://gitlab.techniv.fr/WestCoastSwing/RelativePlacement/badges/master/build.svg)](http://gitlab.techniv.fr/WestCoastSwing/RelativePlacement/commits/master) | ||
3 | |||
4 | This library provide an placement system with the relative placement algorithm used in | ||
5 | West Coast Swing dance competitions. | ||
6 | |||
7 | ## Understading relative placement | ||
8 | |||
9 | Relative placement is a placement system where electors (judges) provide there own placement | ||
10 | of each candidates. | ||
11 | |||
12 | The algorithm consist to search for each place a majority of votes for a candidate at this | ||
13 | placement or a greater placement. | ||
14 | |||
15 | You can refer to [this explain from boogiebythebay.org][1] for all the details. | ||
16 | |||
17 | ## Get RelativePlacementJS | ||
18 | ```shell | ||
19 | npm install relative-placement-js --save | ||
20 | ``` | ||
21 | With node: | ||
22 | ```javascript | ||
23 | var RelativePlacement = require('relative-placement-js'); | ||
24 | ``` | ||
25 | |||
26 | With browser: | ||
27 | ```html | ||
28 | <script src="{BASE_PATH}/node_modules/relative-placement-js/dist/relative-placement.js"></script> | ||
29 | <!-- Or the original ES6 sources --> | ||
30 | <script src="{BASE_PATH}/node_modules/relative-placement-js/lib/relative-placement.js"></script> | ||
31 | ``` | ||
32 | |||
33 | With AngularJS: | ||
34 | ```javascript | ||
35 | angular.module('myApp', ['relative-placement-js']).controller('MyCtrl', [ | ||
36 | '$scope', 'RelativePlacement', | ||
37 | function($scope, RelativePlacement){ | ||
38 | |||
39 | } | ||
40 | ]); | ||
41 | ``` | ||
42 | |||
43 | ## Use RelativePlacementJS | ||
44 | |||
45 | ```javascript | ||
46 | var contest = new RelativePlacement(); | ||
47 | |||
48 | contest.addCandidates(['A','B','C']); | ||
49 | contest.addCandidate('D'); | ||
50 | |||
51 | contest.addVote(['A','B','C','D']); | ||
52 | contest.addVotes([ | ||
53 | ['A','B','C','D'], | ||
54 | ['A','C','B','D'], | ||
55 | ['A','B','D','C'], | ||
56 | ['B','A','C','D'], | ||
57 | ['B','A','D','C'] | ||
58 | ]); | ||
59 | |||
60 | var result = contest.getResult(); // return ['A','B','C','D']; | ||
61 | ``` | ||
62 | |||
63 | [1]: http://www.boogiebythebay.org/sitebuildercontent/sitebuilderfiles/bbb_relativeplacement.pdf | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
gulpfile.js
0 → 100644
1 | /** | ||
2 | * Created by Techniv on 05/12/2016. | ||
3 | */ | ||
4 | |||
5 | const srcPath = './lib/relative-placement.js'; | ||
6 | const distPath = './dist/'; | ||
7 | |||
8 | var gulp = require('gulp'); | ||
9 | var babel = require('gulp-babel'); | ||
10 | var del = require('del'); | ||
11 | |||
12 | gulp.task('default', ['build']); | ||
13 | |||
14 | gulp.task('build',['clean'], ()=>{ | ||
15 | return gulp.src(srcPath) | ||
16 | .pipe(babel({ | ||
17 | presets: ['es2015'] | ||
18 | })) | ||
19 | .pipe(gulp.dest(distPath)); | ||
20 | }); | ||
21 | |||
22 | gulp.task('clean',() => { | ||
23 | return del(distPath); | ||
24 | }); | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | /** | 1 | /** |
2 | * Created by Techniv on 30/11/2016. | 2 | * Created by Techniv on 30/11/2016. |
3 | * @module relative_placement | 3 | * @module relativePlacement |
4 | */ | 4 | */ |
5 | (function (define) { | 5 | (function (definition) { |
6 | module.exports = define(); | 6 | // Node export |
7 | if(global && module && module.exports) return module.exports = definition(); | ||
8 | //Browser export | ||
9 | if(window){ | ||
10 | if(angular && angular.version.major == 1) return angular.module('relative-placement-js').factory('RelativePlacement', definition); | ||
11 | if(requirejs) return define(definition()); | ||
12 | |||
13 | window.RelativePlacement = definition(); | ||
14 | } | ||
7 | })(function(){ | 15 | })(function(){ |
8 | 16 | ||
9 | /** | 17 | /** |
... | @@ -74,7 +82,14 @@ | ... | @@ -74,7 +82,14 @@ |
74 | candidate.votes.push(i); | 82 | candidate.votes.push(i); |
75 | } | 83 | } |
76 | }; | 84 | }; |
77 | RelativePlacement.prototype.addVotes = function () {}; | 85 | |
86 | /** | ||
87 | * | ||
88 | * @param {String[][]} votes | ||
89 | */ | ||
90 | RelativePlacement.prototype.addVotes = function (votes) { | ||
91 | votes.forEach(vote => this.addVote(vote)); | ||
92 | }; | ||
78 | RelativePlacement.prototype.getResult = function () { | 93 | RelativePlacement.prototype.getResult = function () { |
79 | return relativePlacement(this.votes, this.candidateList); | 94 | return relativePlacement(this.votes, this.candidateList); |
80 | }; | 95 | }; |
... | @@ -163,7 +178,6 @@ | ... | @@ -163,7 +178,6 @@ |
163 | return 0; | 178 | return 0; |
164 | }); | 179 | }); |
165 | result = result.concat(proposed.map(candidate => candidate.name)); | 180 | result = result.concat(proposed.map(candidate => candidate.name)); |
166 | cursor = result.length; | ||
167 | proposed.splice(0); | 181 | proposed.splice(0); |
168 | continue; | 182 | continue; |
169 | } | 183 | } | ... | ... |
1 | { | 1 | { |
2 | "name": "relative-placement-js", | 2 | "name": "relative-placement-js", |
3 | "version": "0.0.1", | 3 | "version": "0.0.1", |
4 | "description": "JavaScript Relative Placement calculator for dance competitions.", | ||
5 | "author":{ | ||
6 | "name": "Techniv", | ||
7 | "email": "contact@techniv.fr" | ||
8 | }, | ||
9 | "main": "./lib/relative-placement.js", | ||
10 | |||
11 | "repository":{ | ||
12 | "type": "git", | ||
13 | "url": "http://gitlab.techniv.fr/WestCoastSwing/RelativePlacement" | ||
14 | }, | ||
15 | "bugs": { | ||
16 | "url": "http://gitlab.techniv.fr/WestCoastSwing/RelativePlacement/issues" | ||
17 | }, | ||
18 | |||
4 | "devDependencies": { | 19 | "devDependencies": { |
5 | "gulp": "*", | 20 | "gulp": "*", |
6 | "nodeunit": "*", | 21 | "gulp-babel": "*", |
7 | "mocha": "*", | 22 | "del": "*", |
8 | "karma": "*", | 23 | "babel-preset-es2015": "*", |
9 | "karma-mocha": "*" | 24 | "mocha": "*" |
10 | }, | 25 | }, |
11 | "scripts": { | 26 | "scripts": { |
27 | "build": "./node_modules/.bin/gulp build", | ||
12 | "test" : "./node_modules/.bin/mocha bdd tests/node/**/*Spec.js" | 28 | "test" : "./node_modules/.bin/mocha bdd tests/node/**/*Spec.js" |
29 | }, | ||
30 | "engines": { | ||
31 | "node": ">=6.9.*" | ||
13 | } | 32 | } |
14 | } | 33 | } | ... | ... |
... | @@ -2,7 +2,7 @@ | ... | @@ -2,7 +2,7 @@ |
2 | * Created by Techniv on 30/11/2016. | 2 | * Created by Techniv on 30/11/2016. |
3 | */ | 3 | */ |
4 | var assert = require('assert'); | 4 | var assert = require('assert'); |
5 | var RelativePlacement = require('../../relative-placement'); | 5 | var RelativePlacement = require('../../lib/relative-placement'); |
6 | 6 | ||
7 | describe('RelativePlacement global', () => { | 7 | describe('RelativePlacement global', () => { |
8 | it('should provide RelativePlacement constructor', () => { | 8 | it('should provide RelativePlacement constructor', () => { |
... | @@ -158,5 +158,18 @@ describe('RelativePlacement global', () => { | ... | @@ -158,5 +158,18 @@ describe('RelativePlacement global', () => { |
158 | assert.ok(candidates.every(name => result.indexOf(name) != -1)); | 158 | assert.ok(candidates.every(name => result.indexOf(name) != -1)); |
159 | assert.ok(result.every(name => candidates.indexOf(name) != -1)); | 159 | assert.ok(result.every(name => candidates.indexOf(name) != -1)); |
160 | }); | 160 | }); |
161 | |||
162 | it('should have placements sum in candidates', () => { | ||
163 | election.addVote(['A', 'B', 'C']); | ||
164 | election.addVote(['B', 'A', 'C']); | ||
165 | election.addVote(['A', 'C', 'B']); | ||
166 | |||
167 | election.getResult(); | ||
168 | var candidate = election.candidateList['A']; | ||
169 | |||
170 | assert.equal(candidate.placements.length, 3); | ||
171 | assert.equal(candidate.cumulativePlacement.length, 3); | ||
172 | assert.equal(candidate.votes.length, 4); | ||
173 | }); | ||
161 | }); | 174 | }); |
162 | }); | 175 | }); |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
... | @@ -3,7 +3,7 @@ | ... | @@ -3,7 +3,7 @@ |
3 | */ | 3 | */ |
4 | var assert = require('assert'); | 4 | var assert = require('assert'); |
5 | /** @type RelativePlacement.relativePlacement */ | 5 | /** @type RelativePlacement.relativePlacement */ |
6 | var relativePlacement = require('../../relative-placement').relativePlacement; | 6 | var relativePlacement = require('../../lib/relative-placement').relativePlacement; |
7 | /** @var {TestData[]} */ | 7 | /** @var {TestData[]} */ |
8 | var testDataList = require('./results_data.json'); | 8 | var testDataList = require('./results_data.json'); |
9 | describe('RelativePlacement algo', () => { | 9 | describe('RelativePlacement algo', () => { |
... | @@ -19,6 +19,7 @@ describe('RelativePlacement algo', () => { | ... | @@ -19,6 +19,7 @@ describe('RelativePlacement algo', () => { |
19 | (testData,id) => { | 19 | (testData,id) => { |
20 | testData.id = id; | 20 | testData.id = id; |
21 | it('#'+id+': '+(testData.comment||''), ()=>{ | 21 | it('#'+id+': '+(testData.comment||''), ()=>{ |
22 | id; | ||
22 | var votes = compileVotes(testData); | 23 | var votes = compileVotes(testData); |
23 | 24 | ||
24 | var result = relativePlacement(votes); | 25 | var result = relativePlacement(votes); | ... | ... |
tests/node/displayResults.js
0 → 100644
1 | /** | ||
2 | * Created by Techniv on 07/12/2016. | ||
3 | */ | ||
4 | var RelativePlacement = require('../../lib/relative-placement'); | ||
5 | var data = require('./results_data.json'); | ||
6 | var util = require('util'); | ||
7 | var exitCode = 0; | ||
8 | |||
9 | console.log('############################'); | ||
10 | console.log('# Details of result matrix #'); | ||
11 | console.log('############################'); | ||
12 | console.log(''); | ||
13 | console.log('The cadidate are display in order of placement'); | ||
14 | console.log(''); | ||
15 | console.log('Column:'); | ||
16 | console.log('Expected | (*error)Candidate\t[Votes]\t[Sum matrix (Sum score)]'); | ||
17 | console.log(''); | ||
18 | console.log(''); | ||
19 | console.log(''); | ||
20 | console.log(''); | ||
21 | |||
22 | data.forEach((testCase, num) => { | ||
23 | console.log("#"+ num + ": "+testCase.comment); | ||
24 | |||
25 | var election = new RelativePlacement(); | ||
26 | var votes = compileVotes(testCase); | ||
27 | |||
28 | election.addCandidates(votes[0]); | ||
29 | election.addVotes(votes); | ||
30 | |||
31 | var result = election.getResult(); | ||
32 | var expected = testCase.result; | ||
33 | var candidates = election.candidateList; | ||
34 | |||
35 | result.forEach((candidateName, place) => { | ||
36 | var log = []; | ||
37 | var candidate = candidates[candidateName]; | ||
38 | |||
39 | log.push(expected[place]); | ||
40 | log.push('\t|\t'); | ||
41 | if(candidateName != expected[place]) exitCode = 1; | ||
42 | (candidateName != expected[place]) ? log.push('*') : log.push(' '); | ||
43 | log.push(candidateName); | ||
44 | log.push('\t'); | ||
45 | log.push(util.format(candidate.votes)); | ||
46 | log.push('\t['); | ||
47 | for (var i = 0; i < candidate.placements.length; i++){ | ||
48 | log.push(i==0 ? ' ' : ', '); | ||
49 | log.push(candidate.placements[i]); | ||
50 | log.push('('); | ||
51 | log.push(candidate.cumulativePlacement[i]); | ||
52 | log.push(') '); | ||
53 | } | ||
54 | log.push(' ]'); | ||
55 | |||
56 | console.log(log.join('')); | ||
57 | }); | ||
58 | |||
59 | console.log('-------------------------------------------------------------------'); | ||
60 | console.log(''); | ||
61 | console.log(''); | ||
62 | }); | ||
63 | |||
64 | process.exit(exitCode); | ||
65 | |||
66 | /** | ||
67 | * @param {TestData} testData | ||
68 | * @return {String[][]} | ||
69 | */ | ||
70 | function compileVotes(testData){ | ||
71 | var votes = testData.votes; | ||
72 | var compileVotes = []; | ||
73 | var candidates = Object.keys(votes); | ||
74 | var voteNumber = votes[candidates[0]].length; | ||
75 | |||
76 | for(let i = 0; i < voteNumber; i++){ | ||
77 | let compileVote = []; | ||
78 | for(let name in votes){ | ||
79 | compileVote[votes[name][i]-1] = name; | ||
80 | } | ||
81 | compileVotes[i] = compileVote; | ||
82 | } | ||
83 | |||
84 | return compileVotes; | ||
85 | } | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -45,5 +45,31 @@ | ... | @@ -45,5 +45,31 @@ |
45 | "Couple H": [3,7,7,7,3] | 45 | "Couple H": [3,7,7,7,3] |
46 | }, | 46 | }, |
47 | "result":["Couple A","Couple B","Couple C","Couple D","Couple E","Couple F","Couple G","Couple H"] | 47 | "result":["Couple A","Couple B","Couple C","Couple D","Couple E","Couple F","Couple G","Couple H"] |
48 | }, | ||
49 | { | ||
50 | "comment": "Jose de la Mancha - Test 20x9", | ||
51 | "votes":{ | ||
52 | "101": [11,4,9,14,2,6,15,8,1], | ||
53 | "102": [9,7,19,20,4,8,16,1,10], | ||
54 | "103": [7,9,3,2,5,13,7,6,8], | ||
55 | "104": [14,11,1,16,16,1,17,20,7], | ||
56 | "105": [8,16,18,18,6,3,14,3,11], | ||
57 | "106": [19,14,6,8,12,9,2,9,9], | ||
58 | "107": [2,3,5,11,19,10,6,16,19], | ||
59 | "108": [18,8,16,10,18,14,1,4,17], | ||
60 | "109": [15,10,11,3,20,5,8,17,5], | ||
61 | "110": [12,12,7,4,14,15,18,12,16], | ||
62 | "111": [13,5,2,5,17,17,10,15,18], | ||
63 | "112": [4,17,15,9,13,2,11,2,12], | ||
64 | "113": [5,6,13,12,1,20,5,11,20], | ||
65 | "114": [17,19,10,1,11,11,13,5,13], | ||
66 | "115": [6,15,8,19,3,18,12,19,3], | ||
67 | "116": [3,1,14,13,8,19,9,7,6], | ||
68 | "117": [10,18,17,15,7,7,3,13,2], | ||
69 | "118": [1,20,12,17,10,12,19,10,14], | ||
70 | "119": [16,13,4,6,15,4,4,18,15], | ||
71 | "120": [20,2,20,7,9,16,20,14,4] | ||
72 | }, | ||
73 | "result":["103","101","116","106","102","107","117","109","112","113","105","114","115","118","110","119","111","104","120","108"] | ||
48 | } | 74 | } |
49 | ] | 75 | ] |
... | \ No newline at end of file | ... | \ No newline at end of file | ... | ... |
-
Please register or sign in to post a comment