Search code examples
pythonplaying-cards

"Pop index out of range" for deck of cards


What I currently have is code to build a deck of cards, to shuffle the deck, and to build a hand from that deck.

from random import randint

def make_deck():
    deck = []
    for suit in suits:
        for rank in ranks:
           deck.append((suit,rank))
    return deck

suits = ['spades','hearts','diamonds','clubs']
ranks = ['ace','two','three','four','five','six','seven','eight','nine','ten','jack','queen','king']

deck = make_deck() #list of cards

def shuffle(deck):
    for k in range(100): # do it 100 times
        card = deck.pop(randint(0,51))
        deck.append(card)

def make_hand():
    hand = []
    for k in range(2):
        card = deck.pop(randint(0,51))
        hand.append(card)
    return hand

hand = make_hand()

When I run the program, printing deck will give me the list of cards as I like and then when I try to shuffle the deck, I get an error stating that the pop index is out of range. Not quite sure why it would be out of index since the range (0,51) represents all 52 cards of the deck.

The same error shows up when I try to use the make_hand() function, though not always. Am I using the pop method incorrectly? What do I have to change so that the shuffle function works and the hand will always return two different cards from the deck?


Solution

  • It's safer to write this as

    card = deck.pop(randint(0,len(deck)-1))
    

    Though it's faster if you save that value somewhere.

    But that also points to a problem that your deck has a problem. Are you for loops in the deck creation formatted correctly? It's possible that you're creating less than 52 cards and so when you generate an integer on the high end you're catching that error. This also seems likely if it occasionally happens in make_hand (where you iterate twice) and constantly in shuffle (where you iterate 100 times).

    If your intention is to shuffle cards after hands were dealt, then you definitely need to be using len() or keeping track of the deck size some other way. And even in the make_hand function, you're popping one card and then still trying to draw from a list of size 52 even though you've taken a card out.