Numpy probabilities

Question:

I was just wondering why I’m getting an error from running the code below. I’m trying to use numpy to do probabilities for a text-based game. The code below is not what will be in the game itself. This is just for testing purposes and to learn. Thanks for your answers in advance, and please go easy on me.

from numpy.random import choice

class container:

    def __init__(self):
        self.inv = {'common': ['blunt sword', 'blunt axe'], 'uncommon': ['Dynasty bow', 'Axe', 'Sword'], 'rare': ['Sharp axe'], 'epic': ['Great Sword']}
        self.probabilities = {"common": 50, 'uncommon':25, 'rare': 10, 'epic': 3}
        self.item = choice(self.inv(choice(self.probabilities.keys(), p=self.probabilities.values())))

    def open(self):
        return f'You loot {self.item}'


loot = container().open()
print(loot)

Error:

Traceback (most recent call last):
  File "mtrand.pyx", line 1115, in mtrand.RandomState.choice
TypeError: 'dict_keys' object cannot be interpreted as an integer

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "test.py", line 14, in <module>
    loot = container().open()
  File "test.py", line 8, in __init__
    self.item = choice(self.inv(choice(self.probabilities.keys(), p=self.probabilities.values())))
  File "mtrand.pyx", line 1117, in mtrand.RandomState.choice
ValueError: 'a' must be 1-dimensional or an integer
Asked By: Johnny Niklasson

||

Answers:

As per the documentation of np.random.choice it takes in a 1D array or int a and a probability vector pwhose length is equal to length of a and sums to one. In your case you are feeding probabilities.keys() and inv.keys() which are of type dict_keys. Also, your probability vector doesn’t sum to 1. one way to convert the probability vector to the required format is to divide it by the sum of it. I have make the necessary changes to the code

from numpy.random import choice

class container:

def __init__(self):
    self.inv = {'common': ['blunt sword', 'blunt axe'], 'uncommon': ['Dynasty bow', 'Axe', 'Sword'], 'rare': ['Sharp axe'], 'epic': ['Great Sword']}
    self.probabilities = {"common": 50, 'uncommon':25, 'rare': 10, 'epic': 3}
    self.convert_prob_vector()
    self.item = choice(self.inv[choice(list(self.probabilities.keys()), p=self.probabilities_new)])

def convert_prob_vector(self):
    self.probabilities_new = [x / sum(self.probabilities.values()) for x in self.probabilities.values()]
def open(self):
    return f'You loot {self.item}'


loot = container().open()
print(loot)

Sample Output

You loot Dynasty bow

Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.