Basically, this gives me a list of 500 random decimal numbers that are
rounded to 3 places. However, I also want to make sure that all are
unique.
.uniq() doesn’t guarentee 500 number exactly.
.shuffle() just tosses the collection and doesn’t give you unique
numbers.
You’d better to implement method:
def secure(number, precision)
collection = []
collection |= [SecureRandom.random_number.round(precision)] while
collection.size < number
collection
end
secure(500, 3)
=> collection of 500 unique random numbers.
def secure(number, precision)
collection = []
collection |= [SecureRandom.random_number.round(precision)] while
collection.size < number
collection
end
secure(500, 3)
=> collection of 500 unique random numbers.
One simple way to get what you want is by using a set:
Here’s your method of generating random numbers. Don’t count on it
giving you “secure” random numbers, but this technique won’t care how
you produced them.
#!/usr/bin/env ruby
require ‘set’
def random_numbers(n = 500)
my_set = Set.new
while my_set.size < 500
value = Integer((rand * 1) * 1000) / Float(1000)
my_set << value
end
my_set.to_a
end
def random_numbers(n = 500)
my_set = Set.new
while my_set.size < 500
value = Integer((rand * 1) * 1000) / Float(1000)
my_set << value
end
my_set.to_a
end
puts random_numbers.size
One caveat with this technique: Make sure you build in some “circuit
breaker” protection code. The more numbers you ask this to generate the
more rounds it will take to produce the result. Generating 500 unique
numbers is averaging about 700 rounds. The closer to 1000 you get the
more rounds it will take. Over 1000 and it will never finish.
Basically, this gives me a list of 500 random decimal numbers that are
rounded to 3 places. However, I also want to make sure that all are
unique.
This is a classic “how do I achieve my solution?”, rather than a
“here’s my problem… how can I solve it” post…
Can we back up a second please?
What are you trying to achieve with this list of 500 numbers? And what
do you want to do if the list you have generated does contain
duplicates?
As already said, you can use the .uniq method to remove dupes - but
that might leave you with an array of 496 elements… would that be a
problem? Are you really asking “how do I generate an array of 500
random numbers”?
What do you want to do with these 500 random numbers? Considering that
one user could make a request and get their 500 randoms, and another
user could do the same - there could be duplicates across users. Is
this going to be a problem?
Please try to ask clearer questions, as the way it stands, I could
spend ages of my time coming up with solutions to what I think is
your problem, just to have you say “nope… that’s not what I was
after”. Multiply that across the subscribers to this list, and you’ve
wasted a hell of a lot of peoples’ time around the world :-/
PS BTW Why are you multiplying by 1 in your example code? (and does
that line even work if you paste it into your console, as it explodes
for me with a LocalJumpError… but that may just be Ruby versions…)
One caveat with this technique: Make sure you build in some “circuit
breaker” protection code. The more numbers you ask this to generate the
more rounds it will take to produce the result. Generating 500 unique
numbers is averaging about 700 rounds. The closer to 1000 you get the
more rounds it will take. Over 1000 and it will never finish.
Another caveat is that the Array contains “Float” objects, while the
original question was “500 unique decimals”. Two issues here:
if “decimals” are asked in the problem statement, why then do
we serve Floats in the result?
The problem is that for uniqueness, we need the ‘==’ operator and
on Floats that represent fractional numbers in the decimal system,
equality is not a stable function (as was discussed many times before
…).
So, in all proposed solutions, I would exchange this line:
thanks for responses, the ultimate goal was just to ensure a list of
500 (no more or less) unique random decimals that are 3 places which
would be generated only one time. Currently Im storing them as a float
in the mysql database.
One time for ever? You do realise there’s only 1000 numbers between 0
and 0.999?
After two runs, you’ll have used up the whole pool.
thanks for responses, the ultimate goal was just to ensure a list of
500 (no more or less) unique random decimals that are 3 places which
would be generated only one time. Currently I’m storing them as a float
in the mysql database.
Do yourself a favor and change your migration with a line like this:
t.decimal :number, :precision => 10, :scale => 3
That’s all it takes to use decimals (with 3 digits following the decimal
point)
in the database too.
thanks for responses, the ultimate goal was just to ensure a list of
500 (no more or less) unique random decimals that are 3 places which
would be generated only one time. Currently Im storing them as a float
in the mysql database.
This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.