2016年8月24日水曜日

開発環境

Pythonからはじめる数学入門 (Amit Saha (著)、黒川 利明 (翻訳)、オライリージャパン)の3章(データを統計量で記述する)、3.9(プログラミングチャレンジ)、問題3-4(百分位を求める)をJavaScript(とstatistics.js)で取り組んでみる。

問題3-4(百分位を求める)

CSVファイル(WWDI | Population, total - Japan)

コード(Emacs)

HTML5

<div id="output0"></div>

<input id="nums_data" type="file">

<script src="statistics.js"></script>
<script src="sample4.js"></script>

JavaScript

(function () {
    'use strict';
    Array.prototype.sum = function () {
        var s = 0;

        this.forEach(function (num) {
            s += num;
        });
        return s;
    };
    Array.prototype.mean = function () {
        var s = this.sum(),
            n = this.length;

        return s / n;
    };
    Array.prototype.median = function () {
        var numbers = this.slice(),
            len = numbers.length,
            i1,
            i2,
            median;

        numbers.sort(function (x, y) {
            return x - y;
        });
        if (len % 2 === 0) {
            i1 = len / 2 - 1;
            i2 = i1 + 1;
            median = (numbers[i1] + numbers[i2]) / 2;
        } else {
            i1 = (len + 1) / 2 - 1;
            median = numbers[i1];
        }
        return median;
    };
    Array.prototype.modes = function () {
        var obj = {},
            count,
            num,
            max = 0,
            modes = [];

        this.forEach(function (num) {
            if (obj[num] === undefined) {
                obj[num] = 1;
                if (max === 0) {
                    max = 1;
                }
            } else {
                count = obj[num] + 1;
                obj[num] = count;
                if (count > max) {
                    max = count;
                }
            }
        });
        for (num in obj) {
            if (obj[num] === max) {
                modes.push(parseInt(num, 10));
            }
        }
        return modes;
    };
    Array.prototype.differences = function () {
        var mean = this.mean(),
            diff;

        diff = this.map(function (num) {
            return num - mean;
        });
        return diff;
    };
    Array.prototype.variance = function () {
        var diff = this.differences(),
            squared_diff,
            len = this.length;

        squared_diff = diff.map(function (x) {
            return Math.pow(x, 2);
        });
        return squared_diff.sum() / len;
    };
    Array.prototype.standard_deviation = function () {
        var variance = this.variance(),
            std_deviation = Math.sqrt(variance);

        return std_deviation;
    };
    Array.prototype.percentile = function (p) {
        var numbers = this.slice(),
            n = numbers.length,
            i = n * p / 100 + 0.5,
            k = Math.floor(i),
            f,
            result;

        numbers.sort(function (x, y) {
            return x - y;
        });
        if (k === i) {
            result = numbers[i];
        } else {
            f = i - k;
            result = (1 - f) * numbers[k - 1] + f * numbers[k]
        }
        return result;
    };
}(this));
(function () {
    'use strict';
    var div_output = document.querySelector('#output0'),
        input_nums_data = document.querySelector('#nums_data'),
        range,
        getNumbers,
        display;

    range = function (start, end, step) {
        var nums = [],
            i;

        for (i = start; i < end; i += step) {
            nums.push(i);
        }
        return nums;
    };

    getNumbers = function () {
        var file = input_nums_data.files[0],
            reader,
            numbers = [],
            i,
            max = 100;

        if (file === undefined) {
            for (i = 0; i < max; i += 1) {
                numbers.push(Math.floor(Math.random() * 100) + 1);
            }
            display(numbers);
        } else {
            reader = new FileReader();
            reader.readAsText(file);
            reader.onload = function () {
                var text = reader.result;

                numbers = text.split('\n')
                    .map(function (x) {
                        return x.trim();
                    })
                    .filter(function (x) {
                        return x !== '';
                    })
                    .map(function (x) {
                        return parseFloat(x);
                    });
                display(numbers);
            };
            reader.onerror = function (error) {
                div_output.innerText = error;
            };
        }
    };

    display = function (numbers) {
        var numbers0 = numbers.slice(),
            percentiles = range(5, 100, 5),
            output = '',
            nl = '<br>';

        numbers0.sort(function (x, y) {
            return x - y;
        });
        output +=
            '数のリスト: ' + numbers.join(',') + nl +
            '昇順     : ' + numbers0.join(',') + nl;

        percentiles.forEach(function (p) {
            output += p + '百分位: ' + numbers.percentile(p) + nl;
        });
        div_output.innerHTML = output;
    };

    input_nums_data.onchange = getNumbers;

    getNumbers();
}());

0 コメント:

コメントを投稿