随机数生成器未产生预期的答案Node JS

时间:2018-07-13 21:47:35

标签: node.js random

在Node JS脚本中,正在使用公式来生成两个值之间的随机数。这是函数randomIntInc

function randomIntInc(low, high) {

return Math.floor(Math.random() * (high - low + 1) + low);

}

该函数被调用时具有两个低值和高值:

let randomNumber = randomIntInc(requestedStart, requestedEnd);

console.log(requestedStart)在执行上述行之前会产生542(预期)

console.log(requestedEnd)在执行上述行之前会产生592(预期)

现在,运行上面的行并记录输出会产生任何值,通常在6到50之间。

发生了什么事?在执行随机数之前进行记录会显示正确的范围,但是输出的数字只是不在给定范围内。

这是完整代码(相关代码位于113 )(请忽略与/模因或复活节彩蛋无关的不良行为代码):

// Copyright (C) 2018, Julian Lachniet, Jacob Wysko

// Dependencies
var Discord = require('discord.io'),
    logger = require('winston'),
    auth = require('../auth.json'),
    rn = require('random-number'),
    http = require('http'),
    request = require('request');

// Authorize connection
var bot = new Discord.Client({
    token: auth.token,
    autorun: true
});

// GOOGLE SHEETS API
const fs = require('fs');
const readline = require('readline');
const {google} = require('googleapis');
const SCOPES = ['https://www.googleapis.com/auth/spreadsheets.readonly'];
const TOKEN_PATH = 'credentials.json';

// If bot disconnects, try to reconnect
bot.on('disconnect', function(msg, code) {
    if (code === 0) return console.error(msg);
    bot.connect();
});

// Returns the current timestamp
function timeStamp() {
    return "[" + new Date().toString().split(" G")[0] + "]";
}

// Returns a random integer
function randomIntInc(low, high) {
    return Math.floor(Math.random() * (high - low + 1) + low);
}

// When a message is recieved
bot.on('message', function(user, userID, channelID, message, evt) {
    let valid = false;
    // Log what the user sent (verifies it wasn't sent by the bot)
    if (user !== 'teacher-quotes-bot') {
        console.log(timeStamp() + " " + user + ": " + message);
    }
    // Sends a message with text "message", logs it
    function sendMessage(message) {
        bot.sendMessage({
            to: channelID,
            message: message
        });
        console.log(timeStamp() + " Bot: " + message);
        valid = true;
    }
    // Sends a message based on a list of commands
    function infoMessage(commands, response) {
        if (commands.includes(input)) {
            sendMessage(response);
        }
        validCommands.push(commands);
    }
    // If the message began with a '!' (e.g., !cmd)
    if (message.substring(0, 1) === '!') {
        var args = message.substring(1).split(' ');
        var input = args[0];
        var validCommands = [];
        // Commands
        infoMessage(['accuracy', 'disclaimer', 'terms'], '<#440534402171404289>');
        infoMessage(['android', 'app'], 'https://play.google.com/store/apps/details?id=com.jacobwysko.teacherquotes');
        infoMessage(['format', 'formats', 'formatting'], '"Quote text." - Teacher, MM/DD/YYYY');
        infoMessage(['code', 'git', 'github', 'roadmap', 'trello', 'source', 'sourcecode'], 'https://github.com/wyskoj/TeacherQuotesVersion3\nhttps://github.com/jlachniet/TeacherQuotesBot');
        infoMessage(['faq', 'help', '?'], "You've been <#440504422028804107>ed.");
        infoMessage(['ping', 'pong'], 'Pong!');
        infoMessage(['rule', 'rules'], "You've been <#440500062011916298>ed");
        infoMessage(['apple', 'ios', 'web', 'website'], 'http://jacobwysko.com/teacherquotes');
        infoMessage(['cmd', 'cmds', 'command', 'commands'], 'Valid Commands:\n - accuracy\n - app\n - format\n - github\n - help\n - ping\n - rules\n - website');
        // Easter eggs
        infoMessage(['ivefallenandicantgetup'], 'Stay right there, ' + user + "! Don't worry, help is on the way!");
        infoMessage(['goddammitimpregnant'], '...for the fifteenth damn time!');
        infoMessage(['yeah'], 'boiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii');
        infoMessage(['ohhi'], 'mark');
        infoMessage(['poopity'], 'scoop');
        switch (input) {
            case 'fact':
            case 'randomfact':
                // Sends a random fact
                request('https://spreadsheets.google.com/feeds/list/1ggvma51cj7ryPqfxGv47ZPLuP72keZmFbGE-KBHqbuU/4/public/values?alt=json', function(error, response, body) {
                    let boi = body;
                    let output = JSON.parse(boi);
                    let options = {
                        min: 0,
                        max: 11,
                        integer: true
                    };
                    let randomNumber = rn(options);
                    sendMessage(output["feed"]["entry"][randomNumber]["gsx$randomfact"]["$t"]);
                });
                break;
            case 'randomquote':
                // Sends a random quote
                if (args.length !== 2) {
                    request('https://spreadsheets.google.com/feeds/list/1ggvma51cj7ryPqfxGv47ZPLuP72keZmFbGE-KBHqbuU/1/public/values?alt=json', function(error, response, body) {
                        let output = JSON.parse(body);
                        let options = {
                            min: 0,
                            max: output["feed"]["entry"].length,
                            integer: true
                        };
                        let randomNumber = rn(options);
                        sendMessage(('"' + output["feed"]["entry"][randomNumber]["gsx$quote"]["$t"] + '" - ' + output["feed"]["entry"][randomNumber]["gsx$teacherquoted"]["$t"] + ", " + output["feed"]["entry"][randomNumber]["gsx$date"]["$t"]))
                    });
                } else {
                    console.log("SPECIFICS TEACHER");
                    let requestedTeacher = args[1];
                    request('https://spreadsheets.google.com/feeds/list/1ggvma51cj7ryPqfxGv47ZPLuP72keZmFbGE-KBHqbuU/1/public/values?alt=json', function (error, response, body) {
                        let quotes = JSON.parse(body);
                        console.log(quotes);
                        request('https://spreadsheets.google.com/feeds/list/1ggvma51cj7ryPqfxGv47ZPLuP72keZmFbGE-KBHqbuU/2/public/values?alt=json', function (error, response, body){
                            let ranges = JSON.parse(body);
                            console.log(ranges);

                            let teachers = [];
                            for (i = 0; i < ranges["feed"]["entry"].length; i++){
                                teachers.push(ranges["feed"]["entry"][i]["gsx$teacher"]["$t"]);
                            }

                            let teacherStart = [];
                            for (i = 0; i < ranges["feed"]["entry"].length; i++){
                                teacherStart.push(ranges["feed"]["entry"][i]["gsx$rangestart"]["$t"]);
                            }

                            let teacherEnd = [];
                            for (i = 0; i < ranges["feed"]["entry"].length; i++){
                                teacherEnd.push(ranges["feed"]["entry"][i]["gsx$rangeend"]["$t"]);
                            }

                            let requestedTeacherId = teachers.indexOf(requestedTeacher);

                            let requestedStart = teacherStart[requestedTeacherId];
                            let requestedEnd = teacherEnd[requestedTeacherId];

                            console.log(requestedStart);
                            console.log(requestedEnd);    
                            let randomNumber = randomIntInc(requestedStart, requestedEnd);

                            console.log(requestedTeacher);
                            console.log(randomNumber);
                        });
                    });


                }
                break;
        }
        if (!valid && !['fact', 'randomfact', 'randomquote'].includes(input)) { 
            sendMessage('Invalid command. Type "!command" for a list of commands.');
        }
    } else
    if (user !== 'teacher-quotes-bot' && channelID === '465330717782441986') {
        let validQuoteRegex = /".+"\s-\s\w+,\s\d{2}\/\d{2}\/\d{4}/;
        if (validQuoteRegex.test(message)) { // If the message sent was a valid quote
            let justMessage = message.split('"')[1];
            let justTeacher = message.split('"')[2].substring(3, message.split('"')[2].length - 12);
            let justDate = message.substring(message.length - 10, message.length);
            if (justTeacher.indexOf("(") > -1) {
                justTeacher = justTeacher.substring(0, justTeacher.indexOf("("));
            }
            sendMessage("Message: " + justMessage + "\nTeacher: " + justTeacher + "\nDate: " + justDate);
        } else {
            sendMessage("Invalid Quote");
        }
    }
});  

1 个答案:

答案 0 :(得分:3)

似乎返回的JSON将分配给requestedStartrequestedEnd的值存储为字符串而不是数字。在这种情况下,您需要先将它们转换为数字,然后再对随机数范围进行算术运算。

function randomIntInc(low, high) {
  console.log({
    low,
    high,
    '(high - low) + 1': (high - low) + 1,
    '(high - low + 1) + low': (high - low + 1) + low
  });

  return Math.floor(Math.random() * (high - low + 1) + low);
}

console.log({
  strings: randomIntInc('10', '20'),
  numbers: randomIntInc(10, 20)
});

逐步执行字符串调用'10'和'20'会导致以下操作:

  1. ('20' - '10' + 1):运算顺序将导致首先执行减法运算,这将自动将两个字符串都转换为数字并得出10。最后的加法将简单地将两个数字相加并产生11
  2. 关键部分是最后一个加法,它试图用字符串添加数字。这将导致数字“ 11”转换为字符串,然后与字符串“ 10”串联,结果为“ 1110”。除非您还记得附加符号也用于字符串连接,否则这可能会造成混淆。
  3. 最后,乘法使用随机数乘以字符串值“ 1110”,结果为0-11.1。