Skip to content

Commit b8a8f27

Browse files
authored
Remove unused callback function (#967)
* Refactor player loading and improve UI interactions for regression models * Remove unnecessary assertion in 'initialize' test for nadaraya_watson * Fix test
1 parent 39da817 commit b8a8f27

File tree

12 files changed

+251
-103
lines changed

12 files changed

+251
-103
lines changed

js/platform/game/base.js

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ export default class GameManager {
4545
playButton.type = 'button'
4646
playButton.value = 'Play'
4747
playButton.onclick = () => {
48-
this._loadPlayer(playerSelects, p => {
48+
this._loadPlayer(playerSelects).then(p => {
4949
this.start(p)
5050
})
5151
}
@@ -59,22 +59,20 @@ export default class GameManager {
5959
this._r.appendChild(resetButton)
6060
}
6161

62-
_loadPlayer(players, cb) {
63-
Promise.all(
62+
_loadPlayer(players) {
63+
return Promise.all(
6464
players.map(p => {
6565
if (p.name === 'manual') {
6666
return null
6767
} else if (loadedPlayer[p.name]) {
6868
return new loadedPlayer[p.name](...p.params)
6969
}
70-
return new Promise(resolve => {
71-
import(`./${p.name}.js`).then(obj => {
72-
loadedPlayer[p.name] = obj.default
73-
resolve(new loadedPlayer[p.name](...p.params))
74-
})
70+
return import(`./${p.name}.js`).then(obj => {
71+
loadedPlayer[p.name] = obj.default
72+
return new loadedPlayer[p.name](...p.params)
7573
})
7674
})
77-
).then(cb)
75+
)
7876
}
7977

8078
terminate() {

js/view/gmm.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export default function (platform) {
9999
model = new GMR()
100100
}
101101
const plotter = new GMMPlotter(platform, svg, model, grayscale)
102-
const fitModel = (doFit, cb) => {
102+
const fitModel = doFit => {
103103
if (mode === 'AD') {
104104
if (doFit) model.fit(platform.trainInput)
105105
const outliers = model.probability(platform.trainInput).map(v => {

js/view/isotonic.js

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
import IsotonicRegression from '../../lib/model/isotonic.js'
2+
import Controller from '../controller.js'
23

3-
var dispIsotonic = function (elm, platform) {
4-
const task = platform.task
5-
const fitModel = cb => {
6-
const dim = platform.datas.dimension
4+
export default function (platform) {
5+
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
6+
platform.setting.ml.require = { dimension: 1 }
7+
const controller = new Controller(platform)
8+
const fitModel = () => {
79
const model = new IsotonicRegression()
810
model.fit(
911
platform.trainInput.map(v => v[0]),
@@ -12,16 +14,5 @@ var dispIsotonic = function (elm, platform) {
1214
platform.testResult(model.predict(platform.testInput(1).map(v => v[0])))
1315
}
1416

15-
elm.append('input')
16-
.attr('type', 'button')
17-
.attr('value', 'Fit')
18-
.on('click', () => fitModel())
19-
}
20-
21-
export default function (platform) {
22-
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
23-
platform.setting.ml.require = {
24-
dimension: 1,
25-
}
26-
dispIsotonic(platform.setting.ml.configElement, platform)
17+
controller.input.button('Fit').on('click', () => fitModel())
2718
}

js/view/nadaraya_watson.js

Lines changed: 15 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,31 @@
11
import NadarayaWatson from '../../lib/model/nadaraya_watson.js'
2+
import Controller from '../controller.js'
23

3-
var dispNadarayaWatson = function (elm, platform) {
4+
export default function (platform) {
5+
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
46
platform.setting.ml.reference = {
57
title: 'Kernel regression (Wikipedia)',
68
url: 'https://en.wikipedia.org/wiki/Kernel_regression#Nadaraya%E2%80%93Watson_kernel_regression',
79
}
8-
const fitModel = cb => {
9-
const s = +sgm.property('value')
10-
const auto = autoCheck.property('checked')
10+
const controller = new Controller(platform)
11+
const fitModel = () => {
12+
const s = sgm.value
13+
const auto = autoCheck.element.checked
1114
const model = new NadarayaWatson(auto ? null : s)
1215
model.fit(platform.trainInput, platform.trainOutput)
1316
if (auto) {
14-
sgm.property('value', model._s)
17+
sgm.value = model._s
1518
}
1619

1720
const pred = model.predict(platform.testInput(10))
1821
platform.testResult(pred)
1922
}
2023

21-
elm.append('span').text('auto')
22-
const autoCheck = elm
23-
.append('input')
24-
.attr('type', 'checkbox')
25-
.attr('name', 'auto')
26-
.property('checked', true)
27-
.on('change', () => {
28-
sgm.property('disabled', autoCheck.property('checked'))
29-
})
30-
const sgm = elm
31-
.append('input')
32-
.attr('type', 'number')
33-
.attr('name', 'sigma')
34-
.attr('min', 0)
35-
.attr('value', 0.1)
36-
.attr('step', 0.01)
37-
.property('disabled', true)
38-
elm.append('input')
39-
.attr('type', 'button')
40-
.attr('value', 'Fit')
41-
.on('click', () => fitModel())
42-
}
43-
44-
export default function (platform) {
45-
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
46-
dispNadarayaWatson(platform.setting.ml.configElement, platform)
24+
const autoCheck = controller.input({ type: 'checkbox', label: 'auto' }).on('change', () => {
25+
sgm.element.disabled = autoCheck.element.checked
26+
})
27+
autoCheck.element.checked = true
28+
const sgm = controller.input.number({ min: 0, value: 0.1, step: 0.01 })
29+
sgm.element.disabled = true
30+
controller.input.button('Fit').on('click', () => fitModel())
4731
}

js/view/pcr.js

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
import PCR from '../../lib/model/pcr.js'
2+
import Controller from '../controller.js'
23

3-
var dispPCR = function (elm, platform) {
4+
export default function (platform) {
5+
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
46
platform.setting.ml.reference = {
57
title: 'Principal component regression (Wikipedia)',
68
url: 'https://en.wikipedia.org/wiki/Principal_component_regression',
79
}
8-
const fitModel = cb => {
10+
const controller = new Controller(platform)
11+
const fitModel = () => {
912
const dim = platform.datas.dimension
1013
const model = new PCR()
1114
model.fit(platform.trainInput, platform.trainOutput)
@@ -14,13 +17,5 @@ var dispPCR = function (elm, platform) {
1417
platform.testResult(pred)
1518
}
1619

17-
elm.append('input')
18-
.attr('type', 'button')
19-
.attr('value', 'Fit')
20-
.on('click', () => fitModel())
21-
}
22-
23-
export default function (platform) {
24-
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
25-
dispPCR(platform.setting.ml.configElement, platform)
20+
controller.input.button('Fit').on('click', () => fitModel())
2621
}

js/view/pls.js

Lines changed: 13 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,28 @@
11
import PLS from '../../lib/model/pls.js'
2+
import Controller from '../controller.js'
23

3-
var dispPLS = function (elm, platform) {
4+
export default function (platform) {
5+
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
46
platform.setting.ml.reference = {
57
title: 'Partial least squares regression (Wikipedia)',
68
url: 'https://en.wikipedia.org/wiki/Partial_least_squares_regression',
79
}
8-
const fitModel = cb => {
10+
const controller = new Controller(platform)
11+
const fitModel = () => {
912
const dim = platform.datas.dimension
10-
const l = +elm.select('[name=l]').property('value')
11-
const model = new PLS(l)
13+
const model = new PLS(l.value)
1214
model.init(platform.trainInput, platform.trainOutput)
1315
model.fit()
1416

1517
const pred = model.predict(platform.testInput(dim === 1 ? 100 : 4))
1618
platform.testResult(pred)
1719
}
1820

19-
elm.append('span').text(' l = ')
20-
elm.append('input')
21-
.attr('type', 'number')
22-
.attr('name', 'l')
23-
.attr('min', 1)
24-
.attr('max', platform.datas.dimension)
25-
.attr('value', platform.datas.dimension)
26-
elm.append('input')
27-
.attr('type', 'button')
28-
.attr('value', 'Fit')
29-
.on('click', () => fitModel())
30-
}
31-
32-
export default function (platform) {
33-
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
34-
dispPLS(platform.setting.ml.configElement, platform)
21+
const l = controller.input.number({
22+
label: ' l = ',
23+
min: 1,
24+
max: platform.datas.dimension,
25+
value: platform.datas.dimension,
26+
})
27+
controller.input.button('Fit').on('click', () => fitModel())
3528
}

js/view/rmr.js

Lines changed: 7 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
import RepeatedMedianRegression from '../../lib/model/rmr.js'
2+
import Controller from '../controller.js'
23

3-
var dispRMR = function (elm, platform) {
4+
export default function (platform) {
5+
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
6+
platform.setting.ml.require = { dimension: 1 }
47
platform.setting.ml.reference = {
58
title: 'Repeated median regression (Wikipedia)',
69
url: 'https://en.wikipedia.org/wiki/Repeated_median_regression',
710
}
8-
const fitModel = cb => {
9-
const dim = platform.datas.dimension
11+
const controller = new Controller(platform)
12+
const fitModel = () => {
1013
const model = new RepeatedMedianRegression()
1114
model.fit(
1215
platform.trainInput.map(v => v[0]),
@@ -15,16 +18,5 @@ var dispRMR = function (elm, platform) {
1518
platform.testResult(model.predict(platform.testInput(1).map(v => v[0])))
1619
}
1720

18-
elm.append('input')
19-
.attr('type', 'button')
20-
.attr('value', 'Fit')
21-
.on('click', () => fitModel())
22-
}
23-
24-
export default function (platform) {
25-
platform.setting.ml.usage = 'Click and add data point. Next, click "Fit" button.'
26-
platform.setting.ml.require = {
27-
dimension: 1,
28-
}
29-
dispRMR(platform.setting.ml.configElement, platform)
21+
controller.input.button('Fit').on('click', () => fitModel())
3022
}

tests/gui/view/isotonic.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { getPage } from '../helper/browser'
2+
3+
describe('regression', () => {
4+
/** @type {Awaited<ReturnType<getPage>>} */
5+
let page
6+
beforeEach(async () => {
7+
page = await getPage()
8+
const taskSelectBox = page.locator('#ml_selector dl:first-child dd:nth-child(5) select')
9+
await taskSelectBox.selectOption('RG')
10+
const modelSelectBox = page.locator('#ml_selector .model_selection #mlDisp')
11+
await modelSelectBox.selectOption('isotonic')
12+
})
13+
14+
afterEach(async () => {
15+
await page?.close()
16+
})
17+
18+
test('initialize', async () => {
19+
expect.assertions(0)
20+
const methodMenu = page.locator('#ml_selector #method_menu')
21+
const buttons = methodMenu.locator('.buttons')
22+
23+
const fitButton = buttons.locator('input[value=Fit]')
24+
await fitButton.waitFor()
25+
})
26+
27+
test('learn', async () => {
28+
const methodMenu = page.locator('#ml_selector #method_menu')
29+
const buttons = methodMenu.locator('.buttons')
30+
31+
const methodFooter = page.locator('#method_footer')
32+
await expect(methodFooter.textContent()).resolves.toBe('')
33+
34+
const fitButton = buttons.locator('input[value=Fit]')
35+
await fitButton.evaluate(el => el.click())
36+
37+
await expect(methodFooter.textContent()).resolves.toMatch(/^RMSE:[0-9.]+$/)
38+
})
39+
})
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { getPage } from '../helper/browser'
2+
3+
describe('regression', () => {
4+
/** @type {Awaited<ReturnType<getPage>>} */
5+
let page
6+
beforeEach(async () => {
7+
page = await getPage()
8+
const taskSelectBox = page.locator('#ml_selector dl:first-child dd:nth-child(5) select')
9+
await taskSelectBox.selectOption('RG')
10+
const modelSelectBox = page.locator('#ml_selector .model_selection #mlDisp')
11+
await modelSelectBox.selectOption('nadaraya_watson')
12+
})
13+
14+
afterEach(async () => {
15+
await page?.close()
16+
})
17+
18+
test('initialize', async () => {
19+
const methodMenu = page.locator('#ml_selector #method_menu')
20+
const buttons = methodMenu.locator('.buttons')
21+
22+
const autoCheckbox = buttons.locator('input:nth-of-type(1)')
23+
await expect(autoCheckbox.isChecked()).resolves.toBeTruthy()
24+
const sgm = buttons.locator('input:nth-of-type(2)')
25+
await expect(sgm.getAttribute('value')).resolves.toBe('0.1')
26+
})
27+
28+
test('learn', async () => {
29+
const methodMenu = page.locator('#ml_selector #method_menu')
30+
const buttons = methodMenu.locator('.buttons')
31+
32+
const methodFooter = page.locator('#method_footer')
33+
await expect(methodFooter.textContent()).resolves.toBe('')
34+
35+
const fitButton = buttons.locator('input[value=Fit]')
36+
await fitButton.evaluate(el => el.click())
37+
38+
await expect(methodFooter.textContent()).resolves.toMatch(/^RMSE:[0-9.]+$/)
39+
})
40+
})

tests/gui/view/pcr.test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { getPage } from '../helper/browser'
2+
3+
describe('regression', () => {
4+
/** @type {Awaited<ReturnType<getPage>>} */
5+
let page
6+
beforeEach(async () => {
7+
page = await getPage()
8+
const taskSelectBox = page.locator('#ml_selector dl:first-child dd:nth-child(5) select')
9+
await taskSelectBox.selectOption('RG')
10+
const modelSelectBox = page.locator('#ml_selector .model_selection #mlDisp')
11+
await modelSelectBox.selectOption('pcr')
12+
})
13+
14+
afterEach(async () => {
15+
await page?.close()
16+
})
17+
18+
test('initialize', async () => {
19+
expect.assertions(0)
20+
const methodMenu = page.locator('#ml_selector #method_menu')
21+
const buttons = methodMenu.locator('.buttons')
22+
23+
const fitButton = buttons.locator('input[value=Fit]')
24+
await fitButton.waitFor()
25+
})
26+
27+
test('learn', async () => {
28+
const methodMenu = page.locator('#ml_selector #method_menu')
29+
const buttons = methodMenu.locator('.buttons')
30+
31+
const methodFooter = page.locator('#method_footer')
32+
await expect(methodFooter.textContent()).resolves.toBe('')
33+
34+
const fitButton = buttons.locator('input[value=Fit]')
35+
await fitButton.evaluate(el => el.click())
36+
37+
await expect(methodFooter.textContent()).resolves.toMatch(/^RMSE:[0-9.]+$/)
38+
})
39+
})

0 commit comments

Comments
 (0)