0

I'm writing a function to take a new card from a deck of cards, given that there are already some cards out of the deck.

def trekken(getrokken = []):
    import itertools
    import random

    getrokken = list(getrokken)
    kind = 'HCDS'
    value = '123456789XJQKA'
    deck = ["".join(card) for card in itertools.product(value,kind)]
    for i in range(0, len(getrokken)-1): deck.remove(getrokken[i])
    return(deck[(random.randint(1, len(deck)))])

When I use this for some examples a few times I sometimes get the error message:

 line 16, in trekken
    print(deck[(random.randint(1, len(deck)))])
IndexError: list index out of range

For example with the following input:

trekken(['6H', '3C', '3D', '8C', 'AD', '9D', '7D', 'QC'])

Maybe not the first time, but after a few tries (max. 20) I always get this error message.

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
Roelland
  • 193
  • 9
  • random.randint(low, high) will also yield high, thus len(deck) might not be a good candidate for high, better choose a value smaller by one so try instead `return(deck[random.randint(0, len(deck)-1)])`. Note: The list index in Python starts at `0 ` not `1` as in other languages like `R`. – Dilettant Nov 26 '16 at 17:17
  • 2
    Why not just use `deck = ["".join(card) for card in itertools.product(value,kind) if ''.join(card) not in getrokken]`? Note that your `range()` will exclude the very last card from consideration. – Martijn Pieters Nov 26 '16 at 17:22
  • 2
    FYI http://stackoverflow.com/q/1132941/3001761 – jonrsharpe Nov 26 '16 at 17:23
  • 1
    I get `IndexError: list index out of range` instead, because `random.randint()` **includes** the end point in consideration, so `len(deck)` is always a possibility. You are also not using the first card in the deck by starting at `1`. Use `return random.choice(deck)` instead. – Martijn Pieters Nov 26 '16 at 17:24
  • 1
    @jonrsharpe: which is probably why they create a copy with `getrokken = list(getrokken)`. Not that the list is ever mutated. – Martijn Pieters Nov 26 '16 at 17:26
  • @MartijnPieters, I did that because the input could also be something like trekken({'4C', 'AH'}) – Roelland Nov 26 '16 at 17:30

1 Answers1

1

In Python random.randint(low, high) will also yield high, thus len(deck) might not be a good candidate for high, better choose a value smaller by one so try instead as last line:

return deck[random.randint(0, len(deck)-1)]

Or even more clear - as @jonrsharpe suggests:

return deck[random.randrange(len(deck))]

... or as Martijn Pieters suggests:

return random.choice(deck)

Note: The list index in Python starts at 0 not 1 as in other languages like R.

Dilettant
  • 3,267
  • 3
  • 29
  • 29