Creating a randomized list of numbers between two values

Hey yall,

I've been working with textblaze for a few months now. But, I have run into a couple problems that have run me up a wall.

  1. I have a snippet that generates a randomized list of 20 numbers from a range (form text input for the range). But, on occasion it outputs some obviously not random sequence of numbers. Example (range 1-50): 2, 5,6,7,8,13,17,18,19,20,25,28,29,30 etc. There seems to be a pattern to the numbers becoming consecutive. Code at bottom of this post.

  2. I tried making a new snippet that generates a sequence seq(first,last) and then selects random numbers from that sequence with the randomitem(list, weights) function. Where I've had problems here is changing the value of items in a list. I was using a paired weights list for the second param of randomitem().

Is there a better way to add code to these posts? I've only used the forum a couple of times?

Thanks for your input!
Patrick

Snippet 1:

{note: preview=no}{run: Pool={{^^%5B%5D^^}}
}{endnote}{note}Input First and Last Numbers:
{endnote}{note: insert=no}
{formtext: name=First Number}{formtext: name=Last Number}{endnote}{if: `last number`> `first number` and `first number`> 0}{Pool=unique(map(seq(1,30), x->round(random()*(`last number`-`first number`)+`first number`)))}{else}{Pool={{^^%5B%5D^^}}}{endif}{note: preview=yes}
{formmenu: Comma Separated; default=Line Break; name=Options}
{endnote}{note: insert=yes; preview=yes}{if: options="Comma Separated"}{=join(sort(slice(pool,1,20), (a,b)-> a-b),",")}{else}{=join(sort(slice(pool,1,20), (a,b)-> a-b),"\n")}{endif}{endnote}

Snippet 2:

{run: x=0
Pool={{^^%5B%20%5D^^}}
Weights={{^^%5B%20%5D^^}}
String=""
}{formtext: name=First Number; validate=[["regex": "^(-?\\d+(?:\\.\\d+)?|)$", "message": "This field must be a number."]]}{formtext: name=Last Number; validate=[["regex": "^(-?\\d+(?:\\.\\d+)?|)$", "message": "This field must be a number."]]}{button: Pool=seq(`first number`,`last number`)

Weights=map(seq(1,count(Pool)),v->1)

x=x+1
; label=Generate}

{if: isodd(x)="yes"}{repeat: 2}
{run: selection=randomitem(Pool,Weights)
}{run: Weights[location(Pool,selection)]=0}{=location(Pool,selection)}, {=selection}, {=weights}
{endrepeat}{endif}{=Weights}

Hi @Patrick_Ferguson

Thanks for sharing your findings with us. First, to share a snippet in the community, you can use the insert snippet button on the right side of the post's toolbar. We have already fixed your existing post to show in the proper way.

Answering your questions:

  1. We'll look into how our random numbers are generated and see if we can make improvements to get more distributed results. We'll update you once improved; thanks for reporting.
  2. You can fix this snippet by merging the two formulas selection=randomitem(Pool,Weights) and Weights[location(Pool,selection)]=0 into one run block as follows:

{run: x=0
Pool={{^^%5B%20%5D^^}}
Weights={{^^%5B%20%5D^^}}
String=""
}{formtext: name=First Number; validate=[["regex": "^(-?\d+(?:\.\d+)?|)$", "message": "This field must be a number."]]}{formtext: name=Last Number; validate=[["regex": "^(-?\d+(?:\.\d+)?|)$", "message": "This field must be a number."]]}{button: Pool=seq(`first number`,`last number`)

Weights=map(seq(1,count(Pool)),v->1)

x=x+1
; label=Generate}

{if: isodd(x)="yes"}{repeat: 2}
{run: selection=randomitem(Pool,Weights)
Weights[location(Pool,selection)]=0
}{=location(Pool,selection)}, {=selection}, {=weights}
{endrepeat}{endif}{=Weights}

Thank you for the help! My posts should be a lot easier to read from now on.

Running them in the same code block helps with the variable definitions. But, when the commands run through the repeat only the last run seems to modify weights. This leads to values remaining weighted at 1 and the same number possibly being drawn.

Ex:

In my next try I intend to use the map function to change the values of weights rather than assigning it verbatim. If this is a conflict with list comprehensions it may avoid repeat overstepping.

But, I don't have much time to dabble on the clock with this until later this week.

Also, I tried manually duplicating the run block to have it work multiple times but it selects the same number for each one. The random function seems to select the same number each time.

{run: x=0
Pool={{^^%5B%20%5D^^}}
Weights={{^^%5B%20%5D^^}}
String=""
}{formtext: name=First Number; validate=[["regex": "^(-?\d+(?:.\d+)?|)$", "message": "This field must be a number."]]}{formtext: name=Last Number; validate=[["regex": "^(-?\d+(?:.\d+)?|)$", "message": "This field must be a number."]]}{button: Pool=seq(`first number`,`last number`)

Weights=map(seq(1,count(Pool)),v->1)

x=x+1
; label=Generate}
{if: isodd(x)="yes"}
{run: selection=randomitem(Pool,Weights)
Weights[location(Pool,selection)]=0
}, {=selection}
{run: selection=randomitem(Pool,Weights)
Weights[location(Pool,selection)]=0
}, {=selection}
{run: selection=randomitem(Pool,Weights)
Weights[location(Pool,selection)]=0
}, {=selection}
{=location(Pool,selection)}, {=selection}, {=weights}
{endif}

@Patrick_Ferguson Please replace the {repeat} command with a for loop statement to modify the same weights as follows:

{run: x=0
Pool={{^^%5B%20%5D^^}}
Weights={{^^%5B%20%5D^^}}
String=""
}{formtext: name=First Number; validate=[["regex": "^(-?\d+(?:.\d+)?|)$", "message": "This field must be a number."]]}{formtext: name=Last Number; validate=[["regex": "^(-?\d+(?:.\d+)?|)$", "message": "This field must be a number."]]}{button: Pool=seq(`first number`,`last number`)

Weights=map(seq(1,count(Pool)),v->1)

x=x+1
; label=Generate}

{if: isodd(x)="yes"}
{run: random_numbers={{^^%5B%5D^^}}
weights_list={{^^%5B%5D^^}}

for value in seq(1,2)
selection=randomitem(Pool,Weights)
Weights[location(Pool,selection)]=0
random_numbers=merge(random_numbers, [selection])
weights_list=merge(weights_list, [Weights])
endfor

}
Random selections:{=random_numbers}

Weights:{=weights_list}
{endif}

Please let me know if you need any further assistance.

Thanks for showing me this! it works well. I now have a new tool in my toolbox.

I apologize, I got ahead of myself when I was checking this Snippet last night. The weights function does work as intended. However, the original problem (not random selections) persists in this method too.

I made a quick snippet to show this behavior. It seems that throughout the for loop it is using the same random number for each choice. I hope this helps you all with troubleshooting!

{run: Pool=seq(1,100)}

{run: random_numbers={{^^%5B%5D^^}}
selection={{^^%5B%5D^^}}
for value in seq(1,10)
selection[value]=randomitem(Pool)
random_numbers=merge(random_numbers,selection)

endfor
}
{=random_numbers}

@Patrick_Ferguson Thanks so much for reporting this issue to us; we'll work on getting it fixed soon and let you know once we release that fix.