2016年8月25日木曜日

開発環境

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

問題3-5(グループ度数分布表を作る)

コード(Emacs)

HTML5

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

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

JavaScript

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

        this.forEach(function (num) {
            s += num;
        });
        return s;
    };
    Array.prototype.min = function () {
        var m = this[0],
            num,
            i,
            max = this.length;

        for (i = 1; i < max; i += 1) {
            num = this[i];
            if (num < m) {
                m = num;
            }
        }
        return m;
    };
    Array.prototype.max = function () {
        var m = this[0],
            num,
            i,
            max = this.length;

        for (i = 1; i < max; i += 1) {
            num = this[i];
            if (num > m) {
                m = num;
            }
        }
        return m;
    };    
    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 numbers = [7, 8, 9, 2, 10, 9, 9, 9, 9, 4,
                   5, 6, 1, 5, 6, 7, 8, 6, 1, 10],
        div_output = document.querySelector('#output0'),
        input_nums_data = document.querySelector('#nums_data'),
        createClasses,
        frequentry_table,
        display;

    createClasses = function (numbers, n) {
        var low = numbers.min(),
            high = numbers.max(),

            width = (high - low) / n,
            classes = [],
            a = low,
            b = low + width,
            t;

        for (t = high - width; a < t;) {
            classes.push([a, b]);
            a = b;
            b = a + width;
        }
        classes.push([a, high + 1]);
        return classes;
    };
    frequentry_table = function (numbers, n) {
        var numbers0 = numbers.slice(),
            classes = createClasses(numbers, n),
            table = [];

        numbers0.sort(function (x, y) {
            return x - y;
        });
        classes.forEach(function (c, ci) {
            var a = c[0],
                b = c[1],
                i,
                max,
                num,
                freq = 0;

            for (i = 0, max = numbers0.length; i < max; i += 1) {
                num = numbers0[i];
                if (a <= num && num < b) {
                    freq += 1;
                } else {
                    numbers0 = numbers0.slice(i);
                    break;
                }
            }
            table[ci] = [[a, b], freq];
        });
        return table;
    };

    display = function () {
        var i,
            table,
            row,
            col1,
            col2,
            output = '',
            ci,
            max;
        
        for (i = 1; i < 5; i += 1) {
            table = frequentry_table(numbers, i);
            output += '<table border="1" style="text-align:center">' +
                '<tr><th>点数</th><th>頻度</th></tr>';
            for (ci = 0, max = table.length; ci < max; ci += 1) {
                row = table[ci];
                col1 = row[0];
                col2 = row[1];
                output +=
                    '<tr><td>' + col1[0] + '-' + col1[1] + '</td><td>' + col2 +
                    '</td></tr>';
            }
            output += '</table><br>';        
        }
        div_output.innerHTML = output;
    };

    display();
}());

0 コメント:

コメントを投稿