0

I'm trying to generate n number of times a random integer from 1-100. But first from 1 to 25, the probability of generating it is 1/8. from 26 to 50 is a chance of 1/2. the subrange 51 to 75 is 1/4, and the sub range from 76 to 100 has a 1/8 chance of generating. I know how to generate a random int 1-100, but I'm having trouble coming up with an algorithm with the sub-ranges. Could someone guide me in the right direction? I don't want to use any shortcuts like built in functions if there are for this. I'm also coding in python.

import random

numOfTimes = int(raw_input())
counter = 0
while counter < numOfTimes:
    chance = random.randint(1,8)
    if chance == 1:
        randomNumber = random.randint(1,25)

    if chance == 2 or 3 or 4 or 5:
        randomNumber = random.randint(26,50)

    if chance == 6 or 7:
        randomNumber = random.randint(51,75)

    if chance == 8:
        randomNumber = random.randint(76,100)

    counter = counter + 1
    print randomNumber
user2958457
  • 55
  • 1
  • 4
  • 2
    While many of us would be happy to help answer your question, we are much more likely to understand the problem and provide a helpful answer if you show us what you've already tried. Here's some info on how to provide [Minimal, Complete, Tested and Readable](http://stackoverflow.com/help/mcve) code. – mhlester Feb 19 '14 at 21:54
  • And what is your criteria for "built in functions"? Can you not use random number functions? Is this a limitation placed by an instructor for a homework assignment? – mhlester Feb 19 '14 at 21:55
  • Have you read http://stackoverflow.com/questions/4265988/generate-random-numbers-with-a-given-numerical-distribution or http://stackoverflow.com/questions/2073235/random-weighted-choice ? – runDOSrun Feb 19 '14 at 21:56
  • 1
    `or` doesn't work like you think it does: please read [this question](http://stackoverflow.com/questions/15112125/if-x-or-y-or-z-blah) to understand why `chance == 6 or 7` won't work. – DSM Feb 19 '14 at 23:44
  • yeah I just spent time explaining it in my answer... I wasnt thinking ... there are probably a million places where it is explained (and probably better than I did) – Joran Beasley Feb 19 '14 at 23:51

2 Answers2

3

oops fixed my typo for i,v,r in en... should have been for i,(v,r) in enum...

import random
key = random.random()
for i,(v,r) in enumerate(zip([.125,.625,.875],[(1,25),(26,50),(51,75)])):
    if key <= v:
        return random.randint(*r)
return random.randint(76,100)

something like that?

as to your problem

if chance == 2 or 3 or 4 or 5: #this wont work
    randomNumber = random.randint(26,50)

if chance == 6 or 7: #neither will this
    randomNumber = random.randint(51,75)

both of those are always true

chance == 2 will be True or False, we will assume its False and put False in directly

if 3 is the same as if bool(3) and is always True for ANY number that is not zero, so we will replace our 3 4 and 5 with True

you can hopefully see the problem with if False or True or True or True:

you want something like

if chance == 2 or chance == 3 or chance == 4 or chance == 5:

which can be rewritten as

if chance in [2,3,4,5]:

or

if 2 <= chance <= 5:
Joran Beasley
  • 110,522
  • 12
  • 160
  • 179
0

Why not just draw from 8 numbers and then draw again from 25?

The first draw would determine which quarter of the hundred numbers you picked. Something like this:

n = random.randint(1, 8)
res = random.randint(1, 25)

if n == 1: pass
elif 2<=n<=5: res += 25
elif 6<=n<=7: res += 50
else: res +=75

return res
Bartlomiej Lewandowski
  • 10,771
  • 14
  • 44
  • 75