0

So what I'm trying to do is create a function that'll throw 2 dice n times. For every throw, if at least one dice number is odd, we'll return the sum of the pair's values, if not we just return None. The objective of the program is to return a matrix that has 3 columns and n amount of rows representing each pair of dice thrown. Column 1 would be the value of the first dice, column 2 would be the value of the second dice, and column 3 would either be the sum of 1 & 2 or None.

This is the code I have thus far:

def dice(n):
    rolls = np.empty(shape=(n,3))
    for i in range(n):
        x = random.randint(1,6)
        y = random.randint(1,6)
        if x or y == 1 or 3 or 5:
            sum_2_dice = x + y
            rolls.append(x,y,sum_2_dice)
        if x and y != 1 or 3 or 5:
            sum_2_dice = None
            rolls.append(x,y,sum_2_dice)
    return rolls

Running the function gives me no problems, however when I test it out like dice(2)

I get AttributeError: 'numpy.ndarray' object has no attribute 'append'

I assumed we'd have to start off with an empty numpy matrix, and then be able append it in the for loop to get the the 3 columns (the for loop would repeat n times, and we'd consequently get a matrix with n rows and 3 columns)

We're only allowed to inport numpy and random, btw.

zainy
  • 111
  • 1
  • 1
  • 7

1 Answers1

3

As you are creating a numpy array of the correct size you don't need to append values to it. Instead you need to fill the array with values. For example:

rolls = np.zeros(shape=(2, 3))
# [[ 0.  0.  0.]
#  [ 0.  0.  0.]]

rolls[1,:] = 1,2,3
# [[ 0.  0.  0.]
#  [ 1.  2.  3.]]

Another thing to note is that your if statements are not doing what you think they are. See this question for a good explanation.

So, for your example you would want to do

def dice(n):
    rolls = np.empty(shape=(n, 3))

    for i in range(n):
        x = random.randint(1,6)
        y = random.randint(1,6)

        if {x, y} & {1, 3, 5}:  # Suggested by Elazar in the comments  
        # if x in [1,3,5] or y in [1,3,5]:  # Another way to do it      
            sum_2_dice = x + y
            rolls[i,:] = x, y, sum_2_dice

        else:
            sum_2_dice = 0
            rolls[i,:] = x, y, sum_2_dice

    return rolls

If you have to return a matrix (I don't think there is any benefit) you can simply convert it when you return the value:

return np.matrix(rolls)

You can check the type of the output by doing:

result = dice(2)

print (type(result))
# <class 'numpy.matrixlib.defmatrix.matrix'>
DavidG
  • 24,279
  • 14
  • 89
  • 82
  • Thank you! Okay this makes sense, but a couple questions; (1) why does the output return an 'array'? isn't there a way to get it to be a matrix [perhaps I'm just confused on the difference between a numpy matrix and numpy array, I'll brush up on that), but we're supposed to return a numpy matrix. EDIT: Figured out how to change it to return integers, however I get: `TypeError: int() argument must be a string, a bytes-like object or a number, not 'NoneType' ` whenever None happens to randomly be the sum of a dice throw, so I don't get any outputs anymore :/ – zainy Nov 10 '17 at 12:30
  • @zainy A matrix in Python is strictly 2 dimensional. An array can be N dimensional (see [this](https://stackoverflow.com/questions/4151128/what-are-the-differences-between-numpy-arrays-and-matrices-which-one-should-i-u) question). I have updated my answer to show how to convert the result to a numpy matrix. – DavidG Nov 10 '17 at 13:08