Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 15 of 15
  1. #1
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post

    Simple Simple Random String Generator Acting Erratically?

    Code:
    var strings = new Array();
    strings[0] = "This is string #1." + "<br/>"
    strings[1] = "This is string #2." + "<br/>"
    strings[2] = "This is string #3." + "<br/>"
    strings[3] = "This is string #4." + "<br/>"
    strings[4] = "This is string #5." + "<br/>"
    strings[5] = "This is string #6." + "<br/>"
    strings[6] = "This is string #7." + "<br/>"
    strings[7] = "This is string #8." + "<br/>"
    strings[8] = "This is string #9." + "<br/>"
    strings[9] = "This is string #10." + "<br/>"
    var i = Math.round(Math.random() * 10)
    document.write(strings[i])
    I'm trying to write a very simple string generator script. The script creates an array of 10 strings. It then creates a variable called i, and sets the value of this variable to 0 or 1 multiplied by 10, which will become my random number. It then uses document.write to call the string by passing i as the array's index, making it random. So far, this appears to work.

    However, I've noticed that it actually doesn't: or at least, it doesn't do so consistently. Random strings generated aren't entirely random: they often, as I'm refreshing the page, frequently count down. For example, refreshing the page once, let's assume it calls "This is string #8". Refresh again, and it will call "This is string #7", etc, except that it won't count down through all of them, just a few, then another number, and eventually, after so many refreshes, it will continue to countdown in this way again. It's really odd, and I can't understand why it is working that way. As well as this problem, it also returns undefined occasionaly on refreshing.

    Thanks for any and all help with the above script, it is much appreciated.
    Last edited by Hashim1; 05-23-2012 at 12:07 AM.
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #2
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    WRONG!
    Code:
    var i = Math.round(Math.random() * 10)
    RIGHT!
    Code:
    var i = Math.floor( Math.random() * strings.length );
    As for the "erratic" behavior you described: sounds perfectly reasonable to me. Repeat the testing a billion times or so and see if things don't become more random to your satisfaction. It's easy to hit a sequence in a pseudo-random number generator (you do realize this is PSEUDO random, not 100% genuinely random?) that will look like that. Do a few dozen or hundred or thousand more and you might even get to a place where you get the same number 10 times in a row.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #3
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Old Pedant View Post
    As for the "erratic" behavior you described: sounds perfectly reasonable to me. Repeat the testing a billion times or so and see if things don't become more random to your satisfaction. It's easy to hit a sequence in a pseudo-random number generator (you do realize this is PSEUDO random, not 100% genuinely random?) that will look like that. Do a few dozen or hundred or thousand more and you might even get to a place where you get the same number 10 times in a row.
    I'm unsure what you mean by this exactly. Are you saying it's not actually erratic and that generating random numbers constantly is going to give that sort of result eventually? If so, I assure you there has to be some sort of structure there: dropping by one, then again, then again, then rising to a higher number, then repeating more or less, can't be a simple coincidence. Did you run the script on your own machine?

    WRONG!
    Code:
    var i = Math.round(Math.random() * 10)
    RIGHT!
    Code:
    var i = Math.floor( Math.random() * strings.length );
    Can I ask why that is? Why is it that changing Math.round to Math.floor and * 10 to * strings.length (whose value should be 10 anyway, shouldn't it?) would change the script?

    EDIT: Just tested, nothing. Same thing as before, except that it appears to be a tiny more random. The structure to it dropping a few times then rising, and so on, is still there, however.
    Last edited by Hashim1; 05-23-2012 at 12:30 AM.
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #4
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    I have explained the use of Math.random so many times (including once today) that I'm not going to do that again.

    But I'll show you why yours is wrong:

    Math.random() returns a number GREATER THAN OR EQUAL to 0 and LESS THAN 1.

    In other words 0.000000 to 0.999999 (but to more decimal places).

    So when you do Math.random() * 10 the result will be 0.000000 to 9.999999

    Now, ROUND that resulte.
    0.000000 to 0.49999 ==>> 0
    0.500000 to 1.49999 ==>> 1
    1.500000 to 2.49999 ==>> 2
    ...
    8.500000 to 9.49999 ==>> 9
    9.500000 to 9.99999 ==>> 10 !!!!!

    So YOUR code gets numbers from 0 to 10, *NOT* from 0 to 9!

    Not only that:
    on average 5% of the time it will get 0.
    on average 5% of the time it will get 10.
    on average 10% of the time it will get each of the other digits. So it's not even correctly distributed.

    Anyway, if you want a *GOOD* random number generator, you will have to write your own. Go read Donald Knuth's classic computing books on numbers and algorithms. Give it at least 3 months and you can probably create one that passes *most* of his tests.
    Last edited by Old Pedant; 05-23-2012 at 01:46 AM.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #5
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    I have to ask:
    Total earnings so far: £25.15

    If that "very generous" site is so generous, how come your earnings haven't changed since the first time I saw them.

    You are a wonderful advertisement for why *NOT* to use that site.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #6
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    Here, I'll even do the search for you:
    Need array creation and popping from the middle advice
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #7
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,917
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    Quote Originally Posted by Hashim1 View Post
    I'm
    EDIT: Just tested, nothing. Same thing as before, except that it appears to be a tiny more random. The structure to it dropping a few times then rising, and so on, is still there, however.
    Thta is the randomness of random numbers. You are bound to get sequences of rising numbers 3-4-7-8 and falling numbers 9-8-4-2. It would not be random if each number was alternately higher and lower than the previous one!

    Rather than using a random number which may generate the same number twice or even more in succession, it is best to shuffle the array and then select the quotations in index order. This produces an unbiased shuffle:

    Code:
    <script type="text/javascript">
    
    Array.prototype.shuffle = function() {
    var s = [];
    while (this.length) s.push(this.splice(Math.random() * this.length, 1));
    while (s.length) this.push(s.pop());
    return this;
    }
    
    </script>


    "The generation of random numbers is too important to be left to chance."

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #8
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Old Pedant View Post
    I have explained the use of Math.random so many times (including once today) that I'm not going to do that again.

    But I'll show you why yours is wrong:

    Math.random() returns a number GREATER THAN OR EQUAL to 0 and LESS THAN 1.

    In other words 0.000000 to 0.999999 (but to more decimal places).

    So when you do Math.random() * 10 the result will be 0.000000 to 9.999999

    Now, ROUND that resulte.
    0.000000 to 0.49999 ==>> 0
    0.500000 to 1.49999 ==>> 1
    1.500000 to 2.49999 ==>> 2
    ...
    8.500000 to 9.49999 ==>> 9
    9.500000 to 9.99999 ==>> 10 !!!!!

    So YOUR code gets numbers from 0 to 10, *NOT* from 0 to 9!
    Okay, I think I understand what you're saying here. Basically, my script is getting one more number than it needs to get? Okay, with this in mind, just for curiosity's sake, would changing this line:

    var i = Math.floor(Math.random() * 10)

    to this:

    var i = Math.floor(Math.random() * 9)

    accomplish the same as what you suggested would? If not, could you explain why?

    Also - I've updated my script to what you asked, and it seems to be doing the exact same - except this time it's counting upwards.

    Anyway, if you want a *GOOD* random number generator, you will have to write your own. Go read Donald Knuth's classic computing books on numbers and algorithms. Give it at least 3 months and you can probably create one that passes *most* of his tests.
    I'm not trying to create a perfect random number generator, it doesn't need to be completely perfect - it just needs to generate some sort of random number, and this isn't atm.

    Also, I'm not sure what do you mean by pseudo-random. Is this script not entirely random in the sense that the end result is randomly generated?

    I have to ask:
    Total earnings so far: £25.15

    If that "very generous" site is so generous, how come your earnings haven't changed since the first time I saw them.

    You are a wonderful advertisement for why *NOT* to use that site.
    Hahaa, good question, and I agree - I most certainly am not a good advertisement for it.

    a) I just haven't bothered to update my signature with my current earnings. b) Even if I did update it, it would only have risen by a couple of pounds, because I simply don't buy online enough to be able to take full advantage of it. I assure you, though, if you did buy regularly online, and lived in the UK, you'd be losing out on quite a bit of money in the long run if you didn't use that site. You only need to go as far as the site's forum where members have testified to earning hundreds of pounds in cashback. So, yes - I'm just a terrible advertisement for it.

    Thta is the randomness of random numbers. You are bound to get sequences of rising numbers 3-4-7-8 and falling numbers 9-8-4-2. It would not be random if each number was alternately higher and lower than the previous one!
    Hey there Philip M. The problem is, I'm now certain that the numbers aren't random. I completely understand what you mean by there being chances of generating so many rising and falling numbers, but this most certainly is a pattern. I've just had the numbers 1 through 6, 2 times in a row. Understandable maybe after about a thousand+ executions of the script, but for it to happen every time after no less than 10 times or so, is certainly no coincidence! I urge you to run the script just to see for yourself what I mean.
    Last edited by Hashim1; 05-23-2012 at 10:38 AM.
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #9
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Philip M View Post
    Rather than using a random number which may generate the same number twice or even more in succession, it is best to shuffle the array and then select the quotations in index order. This produces an unbiased shuffle:

    Code:
    <script type="text/javascript">
    
    Array.prototype.shuffle = function() {
    var s = [];
    while (this.length) s.push(this.splice(Math.random() * this.length, 1));
    while (s.length) this.push(s.pop());
    return this;
    }
    
    </script>
    Thanks for that suggestion Philip, I'll bear it in mind for the future. To be honest, the only reason I am writing this script is to become familiar with JS arrays, and in doing so, write a little random string generator script of my own in the process. You may both remember me from a while back as the kid trying to learn JavaScript. I've been on and off, due to not having enough time to actually sit down and learn nowadays due to college, but I'm still learning.
    Last edited by Hashim1; 05-23-2012 at 10:47 AM.
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #10
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,917
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    Why not explore the topic rather than asking others to explain it?

    Code:
    <script type="text/javascript">
    
    for (var k = 1 ; k <= 500; k++) {
    var i = Math.floor(Math.random() * 10) ;  // generates 0-9 (10 integer values)
    if (k%10 == 0) {
    document.write((i) + "<br>");
    }
    else {
    document.write(i + "&nbsp&nbsp&nbsp");
    }
    }
    
    </script>
    If you run this you will notice that the same number is very likely repeated 2, 3 or even 4 times in succession. And of course in any series of 10 some index values will probably not be selected at all. That is the randomness of random numbers. But although I have not run any statistical tests, the output appears entirely random to me.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #11
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Philip M View Post
    Why not explore the topic rather than asking others to explain it?

    Code:
    <script type="text/javascript">
    
    for (var k = 1 ; k <= 500; k++) {
    var i = Math.floor(Math.random() * 10) ;  // generates 0-9 (10 integer values)
    if (k%10 == 0) {
    document.write((i) + "<br>");
    }
    else {
    document.write(i + "&nbsp&nbsp&nbsp");
    }
    }
    
    </script>
    If you run this you will notice that the same number is very likely repeated 2, 3 or even 4 times in succession. And of course in any series of 10 some index values will probably not be selected at all. That is the randomness of random numbers. But although I have not run any statistical tests, the output appears entirely random to me.
    Okay, I suppose I understand what you're saying. The numbers being generated just seemed to count down so methodically every time that it was hard to believe it was at all random. You're sure there's nothing in my script which could possibly be causing it to count down or up like that, and that the generation of the integers is entirely random?
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #12
    Supreme Master coder! Philip M's Avatar
    Join Date
    Jun 2002
    Location
    London, England
    Posts
    17,917
    Thanks
    203
    Thanked 2,531 Times in 2,509 Posts
    Quote Originally Posted by Hashim1 View Post
    Okay, I suppose I understand what you're saying. The numbers being generated just seemed to count down so methodically every time that it was hard to believe it was at all random. You're sure there's nothing in my script which could possibly be causing it to count down or up like that, and that the generation of the integers is entirely random?
    As has been pointed out, the numbers genetated are pseudo-random which is the best that can normally be achieved on a machine. The sequence is not truly random in that it is generated by an entirely deterministic causal process which includes a truly random seed. But if the same starting seed is used, then the same sequence of pseudo-random numbers will be generated. This can of course be useful in some situations, for example testing software.

    For most practical purposes not involving advanced mathemetics or the National Lottery psuedo-random numbers are entirely adequate.

    All the code given in this post has been tested and is intended to address the question asked.
    Unless stated otherwise it is not just a demonstration.

  • #13
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    The only computer languages I ever used (well, I also helped create them, but that's just bragging) that had a truly random number function were various versions of BASIC for the old Atari 8-bit computers. And that's because Atari actually had a HARDWARE register that you could read that was essentially monitoring "white noise". It was only an 8-bit register, so to get a proper value for RND() [same as Math.random()] you had to ask for the value multiple times, but it truly was random enough that this worked.

    So... If you can figure out how to (a) build an electronic "white noise" circuit, (b) interface it to your computer, (c) read the values it gives you, (d) convert those values into a proper replacement for Math.random(), THEN you can have true randomness. Or at least as close as humans can come to duplicating nature. [You could also do this by reading Donald Knuth's classic seminal computer books, esp. the one on Algorithms. And then following his advice on how to achieve better randomness. Caution: The hardware answer may be easier.]
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.

  • #14
    Regular Coder
    Join Date
    Dec 2010
    Location
    Sheffield, UK
    Posts
    138
    Thanks
    81
    Thanked 1 Time in 1 Post
    Quote Originally Posted by Philip M View Post
    As has been pointed out, the numbers genetated are pseudo-random which is the best that can normally be achieved on a machine. The sequence is not truly random in that it is generated by an entirely deterministic causal process which includes a truly random seed. But if the same starting seed is used, then the same sequence of pseudo-random numbers will be generated. This can of course be useful in some situations, for example testing software.

    For most practical purposes not involving advanced mathemetics or the National Lottery psuedo-random numbers are entirely adequate.
    Quote Originally Posted by Old Pedant View Post
    The only computer languages I ever used (well, I also helped create them, but that's just bragging) that had a truly random number function were various versions of BASIC for the old Atari 8-bit computers. And that's because Atari actually had a HARDWARE register that you could read that was essentially monitoring "white noise". It was only an 8-bit register, so to get a proper value for RND() [same as Math.random()] you had to ask for the value multiple times, but it truly was random enough that this worked.

    So... If you can figure out how to (a) build an electronic "white noise" circuit, (b) interface it to your computer, (c) read the values it gives you, (d) convert those values into a proper replacement for Math.random(), THEN you can have true randomness. Or at least as close as humans can come to duplicating nature. [You could also do this by reading Donald Knuth's classic seminal computer books, esp. the one on Algorithms. And then following his advice on how to achieve better randomness. Caution: The hardware answer may be easier.]
    I think you've really missed the point tbh, and Philip M had it right. You made your point that a truly random generator would take a lot more to make, and I appreciate that, but as I think is very clear, I don't need any such thing, it would be simply overkill - a pseudo-random number is more than adequate for the purposes I want it for, being just a practice script which I was wanting to write to familiarize myself properly with arrays.

    Thanks for both of your help. There is one more thing though, which I don't understand. What's the difference between this, what I had originally:

    var i = Math.round(Math.random() * 10)

    and this, what Old Pedant gave me:

    var i = Math.floor( Math.random() * strings.length );

    What does Math.floor do that Math.round doesn't? And why is * strings.length needed instead of * 10 if the value of strings.length is 10 anyway (10 array elements)? Thanks, much appreciated.
    Last edited by Hashim1; 05-24-2012 at 08:44 PM.
    http://www.topcashback.co.uk/ref/hashim1

    ^
    Total earnings so far: £25.15
    A very generous cashback site worth checking out.


  • #15
    Supreme Master coder! Old Pedant's Avatar
    Join Date
    Feb 2009
    Posts
    25,166
    Thanks
    75
    Thanked 4,338 Times in 4,304 Posts
    I explained Math.round() in post #4. EVEN IF YOU HAD USED
    Code:
    var i = Math.round(Math.random() * 9);
    to ensure that you only got results from 0 to 9, you would STILL have the problem that 0 and 9 will only appear HALF AS OFTEN in the results as all the other numbers!

    Math.floor TRUNCATES instead of rounding.

    Example:
    Code:
    Math.random() ==>> 0.000000 thru 0.999999
    
    Math.random() * 10 ==>> 0.000000 thru 9.999999
    
    Math.floor then simply TRUNCATES the floating point number to an integer giving you
    
    0 thru 9
    EVENLY DISTRIBUTED!

    **********

    And why is * strings.length needed instead of * 10 if the value of strings.length is 10 anyway (10 array elements)?
    It's note "NEEDED". It is to protect you against yourself. Tomorrow, you decide to have 17 array elements..or only 7. And you forget to change the 10 to the correct length. If you strings.length it will ALWAYS be right.
    An optimist sees the glass as half full.
    A pessimist sees the glass as half empty.
    A realist drinks it no matter how much there is.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •