Welcome!

By registering with us, you'll be able to discuss, share and private message with other members of our community.

SignUp Now!
  • Guest, before posting your code please take these rules into consideration:
    • It is required to use our BBCode feature to display your code. While within the editor click < / > or >_ and place your code within the BB Code prompt. This helps others with finding a solution by making it easier to read and easier to copy.
    • You can also use markdown to share your code. When using markdown your code will be automatically converted to BBCode. For help with markdown check out the markdown guide.
    • Don't share a wall of code. All we want is the problem area, the code related to your issue.


    To learn more about how to use our BBCode feature, please click here.

    Thank you, Code Forum.

Python Range / empty list issue??

I cant believe how much of a pain I'm having with this right of the bat. I mean I'm loving it just as much but just surprised. I've already conquered dozens of road blocks but I'm getting ready to go to bed. I wonder if someone will have an answer for this by the time I'm up. Same blackjack projects, I've made the amount of cards in a deck much smaller to make cycling through it much faster in testing. When a suit is randomly choses that doesnt have anymore cards left (aka an empty list), I call the generate_random_card function again to just chose another one. Its only 4 choices, shouldnt be a big deal. But the if statement doesnt seam to be catching it. First I had it as this " if available_cards[suit] == []: generate_random_card() " Then I changed it to " if not available_cards[suit]: generate_random_card() ". But neither worked.
Python:
from random import randint, randrange
from copy import deepcopy

# PLAYER AND DEALERS WALLET CASH VALUES
players_wallet = 500
dealers_wallet = 500

# SET CONSTANT VALUES OF CARD SUITS AND FACES TO CREATE DECK
# card_numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
card_numbers = ['A', '2', '3', '4', 'Q', 'K']
suits = ["hearts", "clubs", "spades", "diamonds"]

# ADDITIONAL VARIABLES AND COPIES OF VARS TO MANIPULATE DECK AFTER PULLING CARDS
cards_left_after_removal = []
picked_cards = []

# CREATE FULL 52 CARD DECK
full_deck = {}
for i in range(len(suits)):
    full_deck[suits[i]] = [x for x in card_numbers]
available_cards = deepcopy(full_deck)
# available_cards = full_deck.copy()  # COPY DECK FOR CARD REMOVAL

def generate_random_card():
    # RANDOM NUMBER (0-3) - (HEARTS, CLUBS, SPADES, DIAMONDS)
    random_suit = randrange(0, len(available_cards))
    # IF THE SUIT IS EMPTY GENERATE NEW RANDOM NUMBER
    if not available_cards[suits[random_suit]]:
        print(f'------------ {suits[random_suit].upper()} EMPTY -------------')
        generate_random_card()
    # RANDOM CARD NUMBER OUT OF HOW MANY ARE LEFT FOR THE SUIT
    random_card_index = randrange(0, len(available_cards[suits[random_suit]]))
    # A TEXT REPRESENTATION OF THE EXACT CARD PICKED
    random_card = f'{available_cards[suits[random_suit]][random_card_index]} of {suits[random_suit]}'
    # APPEND TO COLLECTION OF PICKED CARDS
    picked_cards.append(random_card)
    # PRINT CARD PICKED TO SCREEN
    print('1.HEARTS 2.CLUBS 3.SPADES 4.DIAMONDS')
    print(f'----RAW NUMBER DATA--- \nRandom Suit #:{random_suit} Random card index #:{random_card_index}')
    print(f'Length of {suits[random_suit]}: {len(available_cards[suits[random_suit]])}  :: {available_cards[suits[random_suit]]}')
    print(f'Random pick: {random_card}')
    # CALLING remove_card_from_deck()
    remove_card_from_deck(random_suit, random_card_index)
    print('Available Cards:')
    print('\n'.join([f'{k}: {v}' for k, v in available_cards.items()]))
    print()


def remove_card_from_deck(suit, num):
    available_cards[suits[suit]].pop(num)

while True:
    generate_random_card()
    print(f'Your cards so far:\n{picked_cards}')
    low_num = 0
    for key in available_cards:
        low_num += len(available_cards[key])
    if low_num <= 0:
        print('Game over')
        break

    ans = input("Pick another card? (Y/N):")
    if ans.lower() == 'n':
        break
 
I'm not sure if this is what you want but, If the pull is from an empty list, this will reset the deck.
Added a try block in the while loop

Python:
while True:
    try:
        generate_random_card()
    except ValueError:
        full_deck = {}
        for i in range(len(suits)):
            full_deck[suits[i]] = [x for x in card_numbers]
        available_cards = deepcopy(full_deck)

    print(f'Your cards so far:\n{picked_cards}')
    low_num = 0
    for key in available_cards:
        low_num += len(available_cards[key])
    if low_num <= 0:
        print('Game over')
        break

    ans = input("Pick another card? (Y/N):")
    if ans.lower() == 'n':
        break
 
Well no. I don't want a try block because I shouldn't get any errors. And I don't want to reset the deck if a list is empty because I already have it so when there are no cards left in the deck at all the program will end. Only I haven't got to see that work because it hasn't let me get that far yet. See the full_deck is actually in the form of a dictionary. It has 4 keys which are the 4 suits "hearts", "clubs", "spades", "diamonds". And the values for each one is the 12 faces/ numbers except to make testing the process a lot quicker and easier I temporarily cut the amount of cards in half. Instead of 12 I just put 6 in there. My random generator is working perfectly. First it picks a random number (0-3) for the suits. Then it picks a random card only from what is still remaining in the deck. However when one suit runs out of cards (meaning the list is empty) then it goes to generate another random card and if it chooses that suit which is empty I'm trying to tell the program "Nope that suit isn't going to work. It has no cards left so go around again and try another suit" until they're all empty. But that's where im having the trouble. I have an if statement that I think should be catching that but it's not
 
This line is where the error is.
random_suit = randrange(0, len(available_cards))
There is no range between 0 and 0.
Ya the if statement is supposed to block that from happening.
# IF THE SUIT IS EMPTY GENERATE NEW RANDOM NUMBER
if not available_cards[suits[random_suit]]:
print(f'------------ {suits[random_suit].upper()} EMPTY -------------')
generate_random_card()
 
This line is where the error is.
random_suit = randrange(0, len(available_cards))
There is no range between 0 and 0.
I figured it out. The problem seemed to be with calling a function that It was already inside I guess. I dont know what exact problem that boils down to but heres my revision which is now working perfectly.
Python:
from random import randint, randrange
from copy import deepcopy

# PLAYER AND DEALERS WALLET CASH VALUES
players_wallet = 500
dealers_wallet = 500

# SET CONSTANT VALUES OF CARD SUITS AND FACES TO CREATE DECK
# card_numbers = ["A", "2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K"]
card_numbers = ['A', '2', '3', '4', 'Q', 'K']
suits = ["hearts", "clubs", "spades", "diamonds"]

# ADDITIONAL VARIABLES AND COPIES OF VARS TO MANIPULATE DECK AFTER PULLING CARDS
cards_left_after_removal = []
picked_cards = []

# CREATE FULL 52 CARD DECK
full_deck = {}
for i in range(len(suits)):
    full_deck[suits[i]] = [x for x in card_numbers]
available_cards = deepcopy(full_deck)
# available_cards = full_deck.copy()  # COPY DECK FOR CARD REMOVAL

def generate_random_card():
    # RANDOM NUMBER (0-3) - (HEARTS, CLUBS, SPADES, DIAMONDS)
    random_suit = randrange(0, len(available_cards))
    # IF THE SUIT IS EMPTY GENERATE NEW RANDOM NUMBER
    if not available_cards[suits[random_suit]]:
        while not available_cards[suits[random_suit]]:
            print(f'------------ {suits[random_suit].upper()} EMPTY -------------')
            random_suit = randrange(0, len(available_cards))
        # generate_random_card()
    # RANDOM CARD NUMBER OUT OF HOW MANY ARE LEFT FOR THE SUIT
    random_card_index = randrange(0, len(available_cards[suits[random_suit]]))
    # A TEXT REPRESENTATION OF THE EXACT CARD PICKED
    random_card = f'{available_cards[suits[random_suit]][random_card_index]} of {suits[random_suit]}'
    # APPEND TO COLLECTION OF PICKED CARDS
    picked_cards.append(random_card)
    # PRINT CARD PICKED TO SCREEN
    print('1.HEARTS 2.CLUBS 3.SPADES 4.DIAMONDS')
    print(f'----RAW NUMBER DATA--- \nRandom Suit #:{random_suit} Random card index #:{random_card_index}')
    print(f'Length of {suits[random_suit]}: {len(available_cards[suits[random_suit]])}  :: {available_cards[suits[random_suit]]}')
    print(f'Random pick: {random_card}')
    # CALLING remove_card_from_deck()
    remove_card_from_deck(random_suit, random_card_index)
    print('Available Cards:')
    print('\n'.join([f'{k}: {v}' for k, v in available_cards.items()]))
    print()


def remove_card_from_deck(suit, num):
    available_cards[suits[suit]].pop(num)

while True:
    generate_random_card()
    print(f'Your cards so far:\n{picked_cards}')
    low_num = 0
    for key in available_cards:
        low_num += len(available_cards[key])
    if low_num <= 0:
        print('Game over')
        break

    ans = input("Pick another card? (Y/N):")
    if ans.lower() == 'n':
        break
 

New Threads

Buy us a coffee!

Back
Top Bottom