0

I am trying to create a program that accepts two lists. The first list being any number, the second list being the probability of the number being output. The program will ask for input on the number and then probability. The program then merges these two so they map each other. The program should then return one number based on the probability entered.

I have created this program and it does this, I just have one question, how can I get it so that for to probability list, you can enter floats (0.1, 0.2). I can do this but then other parts of the code return errors. Also how can I get it so the probability that the user enters can only add up to 1 if floats are used (0.5, 0.5) or 10 if floats aren't used?

pos_values = [] 
probability = []
maxLengthList = 5

while len(pos_values) < maxLengthList:
        number = input("Enter a number: ")
        pos_values.append(number)
        prob = input("Enter a probability: ")
        probability.append(prob)

cumulative_probability = list(zip(pos_values, probability))

prob = [val for val, cnt in cumulative_probability for i in range(cnt)]
outcome = []
for i in range (1):
    outcome.append(random.choice(prob))

print('Possible outcome returned is: ', outcome)

My code does exactly what i want it to, my question is how can i make so that the sum of the probabilities entered can't go over 1 or 10.

Cœur
  • 37,241
  • 25
  • 195
  • 267
noodle
  • 19
  • 1
  • 2
  • 9
  • 1
    possible duplicate of [A weighted version of random.choice](http://stackoverflow.com/questions/3679694/a-weighted-version-of-random-choice) – tzaman May 06 '15 at 20:44
  • @tzaman does'nt explain how to use floats or ensure probability in list can only = 1 or 10, which is my question – noodle May 06 '15 at 21:01

2 Answers2

0

This is the code that you require:

pos_values = []
probability = []
maxLengthList = 5

while len(pos_values) < maxLengthList:
    number = input("Enter a number: ")
    pos_values.append(number)
    prob = input("Enter a probability: ")
    probability.append(prob)

all_values = list(zip(pos_values, probability))

print all_values

prob = [cnt for val, cnt in all_values]
if sum(prob) > 1.0:
    print "Error in probabilities"
else:
    lookup = input("Enter probability to search: ")
    for val, cnt in all_values:
        if cnt == lookup:
            print val

Now, a quick analysis of your code:

  • You can't range over a float, as in, range(cnt)

  • range(1) always outputs 0, hence no point using it in your code. In fact, I wonder what's the rational behind using it in a loop.

Jerry Ajay
  • 1,084
  • 11
  • 26
  • i didn't want to search a probability i wanted the code to output one of the numbers depending on the probability associated with it. Also ensuring collectively the probabilities only sum to 1 – noodle May 06 '15 at 21:21
  • The second part is taken care of in the code. I still can't understand the first part: what do you mean by "output one of the numbers depending on the probability associated with it."? – Jerry Ajay May 06 '15 at 21:25
  • For example if outcomes entered are 1,2,3,4 and probabilities enetered are 0.1,0.1, 0.1 and 0.7, it is most likely the program will return a 4 as it highest probability. The code should return/print 1 outcome entered. – noodle May 06 '15 at 22:08
  • which my code does, i just can't make it so that you can only enter probabilities which sum to 10, so if it goes over 10 itll give an error message. – noodle May 06 '15 at 22:08
0

The problem lies in the list comprehension. The argument of range must be a integer, or else it will throw a error.

A simpler, more pythonic way of achieving the effect you want is the following:

    def returnRandom(probability_distribution):
        r = random.random()
        for value, prob in probability_distribution:
            r -= prob
            if r <= 0: return value
        print("Error! The total probability was less than one!")

You could also format the probabilities on the list to store the cumulative probability instead, and then the code will simplify itself:

    def returnRandom(probability_distribution):
        r = random.random()
        for value, cum_prob in probability_distribution:
            if r <= cum_prob: return value
Jsevillamol
  • 2,425
  • 2
  • 23
  • 46
  • I wanted it so the user could enter the outcomes and probabilties @jsevillamol – noodle May 06 '15 at 21:22
  • @noodle First check that the input lies between the values. Then get the cumulative_probability. If it ever surpases 1 or 10 (I'n not seeing why you would like a probability weighted over 10, but whatever) raise an error. – Jsevillamol May 07 '15 at 12:49