Is there a bug in this - python

I am totally new to programming. This is my second program so far. I have two challenges in this code.
For most of the initial runs this works fine in pycharm but after few runs this gives an error message like below. The bloc of code which is causing this error seems to be executing in the beginning and then its giving this error. Please someone help me with this.
Error message:
Traceback (most recent call last):
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 81, in <module>
play_game()
File "D:\Python\Practice\100 Days of coding\Day 11\Black Jack.py", line 70, in play_game
while comp_score < 17:
TypeError: '<' not supported between instances of 'NoneType' and 'int'
Challenge 2: I have overserved that the cards stored for computer alter occasionally. I am unable to figure out why. Please help.
import random
def play_game():
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
card = random.choice(cards)
return card
def calculate_score(card_list):
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
else:
if 11 in card_list and sum(card_list) > 21:
card_list.remove(11)
card_list.append(1)
return sum(card_list)
def game_result():
print(f"Computer cards are {comp_cards} and computer score is {comp_score}.")
print(f"Your cards are {user_cards} and score is {user_score}.")
if comp_score == user_score:
print("Your scores are equal. Match Draw.")
elif user_score == 0:
print("Yay Black Jack! You win!")
elif comp_score == 0:
print("Computer has Black Jack. You loose.")
elif user_score > 21:
print("You went over 21. You loose.")
elif comp_score > 21:
print("Computer score went over 21. You win!")
elif user_score > comp_score:
print("You won!")
else:
print(f"Computer score {comp_score} is greater than your score {user_score}.\n You loose.")
print("Welcome to BlackJack!")
comp_cards = []
user_cards = []
for _ in range(2):
comp_cards.append(deal_card())
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
print(f"Computer cards {comp_cards}")
print(f"Your cards are {user_cards} and your score is: {user_score}")
pass_ = False
while pass_ == False:
deal_a_new_card = input("Type 'y' to get another card and 'n' to pass. : ")
if deal_a_new_card == "y":
user_cards.append(deal_card())
user_score = calculate_score(user_cards)
else:
pass_ = True
if user_score > 21:
pass_ = True
print(f"Your cards are {user_cards} and your score is: {user_score}")
comp_score = calculate_score(comp_cards)
while comp_score < 17:
comp_cards.append(deal_card())
comp_score = calculate_score(comp_cards)
game_result()
play_again = 'y'
while play_again == "y":
play_game()
play_again = input("\nWould you like to play again? Enter 'y' to play. : ")

This occurs because there are some circunstances where calculate_score() is not returning any value.
You are only returning a value when 'the sum isn't 21' or 'when it's equal to 21 AND there are 2 cards'. But you should also return value if you got a sum of 21 in more than 2 cards.
So you need to include in line 13th of your code:
if sum(card_list) == 21:
if len(card_list) == 2:
return 0
#From here on:
else:
return another_value

Related

Blackjack python game

I have to create a blackjack game in python in which the user inputs the number of decks that are being used and the amount of money the user wants to bet. The rules are: o The player places his bet (should be read from the keyboard).
o The dealer and player are dealt two cards (one card of the dealer should be hidden).
o If the player has 21 he wins his bet; else if the dealer has 21 then the dealer wins and the player loses his bet.
o The player can only select to draw a new card (hit) or pass. Repeat until the player passes or busts. If the player goes above 21 then he busts.
o Then the dealer draws cards (automatically) until he either busts or reaches 17 or higher.
o Values of cards: A= 1 or 11 (the highest that does not bust you) and J=Q=K=10
o Note: in blackjack there are more actions: insurance, double, split; those are not required to be implemented as they would make the code you have to produce much, much longer and harder
I will show you my code below when I tried to run it, it said that the name "total" is not defined on the function game, but earlier on I have already defined it. I don't know how can i fix it.
import random
N=int(input("Please enter number of decks of cards used: "))
deck= [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
wins=0
losses=0
chip_pool = 100
bet = 1
def deal(deck):
hand = []
for i in range(2):
random.shuffle(deck)
card=deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def play_again():
again = input("Do you want to play again? (Y/N) : ").lower()
if again == "y":
dealer_hand = []
player_hand = []
deck = [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]*N
game()
else:
print("Thank you for playing.")
exit()
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
def hit(hand):
card = deck.pop()
if card == 11:
card = "J"
if card == 12:
card = "Q"
if card == 13:
card = "K"
if card == 14:
card = "A"
hand.append(card)
return hand
def print_results(dealer_hand, player_hand):
clear()
print("\n WELCOME TO BLACKJACK!\n")
print("The dealer has a " + str(dealer_hand) + "for a total of" + str(total(dealer_hand)))
print("You have a" + str(player_hand) + "for a total of" + str(total(player_hand)))
def blackjack(dealer_hand, player_hand):
global wins
global losses
if total(player_hand) == 21:
print_results(player_hand,dealer_hand)
print("Congratulations! You got a blackjack.\n")
wins = wins + 1
play_again()
elif total(dealer_hand) == 21:
print_results(dealer_hand,player_hand)
print("Sorry you lose. The dealer got a blackjack.\n")
chip_pool -= bet
loses = loses + 1
play_again()
def score(dealer_hand,player_hand):
if total(player_hand) == 21:
print_results(dealer_hand, player_hand)
print("Congratulations! You got a blackjack1\n")
elif total(dealer_hand) == 21:
print_results(dealer_hand, player_hand)
print("Sorry you lose. The dealer go a blackjack\n")
elif total(player_hand) > 21:
print_results(dealer_hand, player_hand)
print("Sorry, you busted. You lose.\n")
elif total(dealer_hand) > 21:
print_results(dealer_hand, player_hand)
print("Dealer busts. You win!\n")
chip_pool += bet
elif total(player_hand) < total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Sorry, the score is not higher than the dealer. You lose.\n")
chip_pool -= bet
elif total(player_hand) > total(dealer_hand):
print_results(dealer_hand, player_hand)
print("Congratulations. Your score is higher than the dealer. You win.\n")
chip_pool += bet
elif total(player_hand) == total(dealer_hand):
print_results(playe_hand, dealer_hand)
print("There is a tie. In a tie dealer always wins!\n")
chip_pool -= bet
def make_bet():
global bet
bet = 0
print("What amount of chips would you like to bet? ")
while bet == 0:
bet_comp = input()
bet_comp = int(bet_comp)
if bet_comp >= 1 and bet_comp <= chip_pool:
bet = bet_comp
else:
print("Invalid bet, you only have" + str(chip_pool) + "remaining")
def game():
choice = 0
print("Welcome to Blackjack!\n")
dealer_hand = deal(deck)
player_hand = deal(deck)
print("The dealer is showing a " +str(dealer_hand[0]))
make_bet()
print("You have a " + str(player_hand))
blackjack(dealer_hand, player_hand)
quit = False
while not quit:
choice = input("Do you want to [H]it, [S]tand, or [Q]uit: ").lower()
if choice == 'h':
hit(player_hand)
print(player_hand)
if total(player_hand) > 21:
print("You busted")
chip_pool -= bet
play_again()
elif choice == "s":
while total(dealer_hand) < 17:
hit(dealer_hand)
print(dealer_hand)
if total(dealer_hand) > 21:
print("Dealer busts. You win!")
chip_pool += bet
play_again()
score(dealer_hand, playe_hand)
play_again()
elif choice == "q" :
print("Thank you for playing. Hope you enjoyed!")
quit = True
exit()
if __name__ == "__main__":
game()
You have not defined the function total that you call. Try adding this to your code
def total(array):
total = 0
for card in array:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
However I see some more issues in your code that will need fixing later on! Stand or Quit do nothing currently, and on busting there is an exception thrown since chip_pool never had a value assigned to it
EDIT 1:
You defined a function
def total_hand():
total = 0
for card in hand:
if card == "J" or card == "Q" or card == "K":
total = total + 10
elif card == "A":
if total >=11:
total = total + 1
else:
total = total + 11
else:
total = total + card
return total
Similar to what I suggested. Maybe it was just a typo but you need to do the following
Rename the function from total_hand to total OR call total_hand
Change the definition from total_hand() to total_hand(hand)

When my code not exiting while loop in python?

It's a black jack game project. When user_score > 21 or 21 , it shold exit the while loop but it is not exiting while loop.I am new in coding. Plese tell me where is the problem.
I don't want to use break command. Because from which tutorial I am learning she has not taught me it yet.
You can get an idea of black jack game here.247blackjack
I tried these lines of code.
import random
def deal_card():
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
random_index = random.randint(0,(len(cards)-1))
random_card = cards[random_index]
return random_card
def want_another_card():
want_card = input("Want another card type 'y' for yes and type 'n' for no.")
return want_card
user_card = []
computer_card = []
for x in range(0,2):
user_card.append(deal_card())
computer_card.append(deal_card())
def calculate_score(list):
score = sum(list)
return score
user_score = calculate_score(user_card)
computer_score =calculate_score(computer_card)
#final score function
def final_score_calculation():
while calculate_score(computer_card)< 17:
computer_card.append(deal_card())
line_gap()
print(f"Your final hand: {user_card}, final score: {user_score}")
print(f"Computer's final hand: {computer_card}, final score: {computer_score}")
if user_score > computer_score and user_score < 21:
winner = "User"
print(f"{winner} wins")
elif computer_score > user_score and computer_score < 21:
winner = "computer"
print(f"{winner} wins")
elif computer_score > 21:
print("Computer busted. You win.")
elif user_score > 21:
print("User busted, Computer wins")
elif user_score == 21:
print("user wins")
elif computer_score == 21:
print("computer wins")
elif computer_score == user_score:
print("It's a draw")
should_continue = True
while should_continue == True:
print(f"Your cards: {user_card}, current score {calculate_score(user_card)}")
print(f"computer's first card {computer_card[0]}")
#checking if user or computer has a black jack
if user_score == 21 and len(user_card) == 2:
print("User has the blackJack. You win")
should_continue = False
elif computer_score ==21 and len(computer_card) == 2:
print("Computer has the black jack .You lose")
should_continue = False
#checking if they got busted or got 21
if user_score > 21: #checking user
if 11 in user_card:
usr_indx_pos=user_card.index(11)
user_card[usr_indx_pos] = 1
if user_score > 21:
print("you got busted.You lose.")
should_continue = False
elif user_score ==21:
print("you have 21 . you win")
should_continue = False
else:
print("you got busted.You lose.")
should_continue = False
elif computer_score > 21: #checking computer
if 11 in computer_card:
com_indx_pos = computer_card.index(11)
computer_card[com_indx_pos] = 1
if computer_score > 21:
print("computer busted. you win")
should_continue = False
else:
print("computer got busted. You win")
should_continue = False
elif user_score ==21:
print("you win. you got 21")
should_continue = False
elif computer_score ==21:
print("computer win. computer got 21")
should_continue = False
line_gap()
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
Assuming your complaint is that it is prompting you if you want another card even after you bust (or win), the solution is to ensure you don't issue that prompt when the loop is supposed to be done anyway. Just change:
if want_another_card() == "y":
to:
if should_continue and want_another_card() == "y":
This will cause it to do the final_score_calculation() call in the else, which may be redundant; if it shouldn't report the results again when someone has already busted or got exactly 21, wrap the whole of:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
in a check to see if it already knows it's done, making it:
if should_continue:
if want_another_card() == "y":
user_card.append(deal_card())
user_score = calculate_score(user_card)
else:
final_score_calculation()
should_continue = False
so it does no additional work when it already knows the game is over.

Blackjack game not functioning on second restart

############### Our Blackjack House Rules #####################
## The deck is unlimited in size.
## There are no jokers.
## The Jack/Queen/King all count as 10.
## The the Ace can count as 11 or 1.
## Use the following list as the deck of cards:
## cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
## The cards in the list have equal probability of being drawn.
## Cards are not removed from the deck as they are drawn.
## The computer is the dealer.
from replit import clear
from art import logo
import random
cards = [11, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10, 10]
computers_first_card = random.choice(cards)
# print(score)
# print(initial_hand)
def play_again():
play_again = input("Play again? y or n: ")
if play_again == "n":
return False
else:
clear()
blackjack_game()
def ace_check(hand, score):
if 11 in hand and score > 21:
hand[11] = 1
score - 10
def blackjack_game():
print(logo)
playing_game = True
initial_hand = [random.choice(cards), random.choice(cards)]
score = sum(initial_hand)
computers_score = computers_first_card
computers_hand = [computers_first_card]
while playing_game:
print(f"Your cards: {initial_hand}, current score: {score}")
print(f"Computer's first card: {computers_first_card}")
draw_again = input("Type 'y' to get another card, type 'n' to pass: ")
if draw_again == 'y':
draw = random.choice(cards)
ace_check(initial_hand, score)
if draw + score > 21:
initial_hand.append(draw)
score += sum(initial_hand) - score
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_first_card}")
print("You Lose!")
if play_again() == False:
playing_game = False
else:
play_again()
else:
initial_hand.append(draw)
score += sum(initial_hand) - score
else:
while computers_score < score:
draw = random.choice(cards)
ace_check(computers_hand, computers_score)
if draw + computers_score > 21:
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_hand}, final score: {computers_score}")
print("Computer went over 21 on draw!")
print("You Win!")
if play_again() == False:
playing_game = False
else:
play_again()
else:
computers_hand.append(draw)
computers_score = sum(computers_hand)
if computers_score > score:
print(f"Your final hand: {initial_hand}, final score: {score}")
print(f"Computer's final hand: {computers_hand}, final score: {computers_score}")
print("You Lose!")
if play_again() == False:
playing_game = False
else:
play_again()
play_game = input("Do you want to play a game of Blackjack? Type 'y' or 'n': ")
if play_game == "y":
clear()
blackjack_game()
In the above code, on replit, if I go over 21 after restarting an initial game when prompted, and inputing 'n' to end the program, the input print from:
def play_again():
play_again = input("Play again? y or n: ")
if play_again == "n":
return False
else:
clear()
blackjack_game()
Gets printed twice and breaks my program.
The first game always works properly. I can properly input 'n' to stop the program, but once I input I'd like to play another game, when endgame arrives again and I try to stop with inputing 'n' into play_again(), I get asked the same input twice.
Any ideas what I'm doing wrong? Here's my replit of the program so far below:
https://replit.com/#AbrahamFrancis1/blackjack-start#main.py

Need help on why my black jack game Getting 'IndexError: pop from empty list' Error

I was trying to make a blackjack game and when I When I enter H or D for the choice input, the console doesn't allow any of my inputs apart from Ctrl+C for output1 and it produces an error shown in ouput2 when I enter S for the choice input
My code
from random import choice, shuffle
plain_cards = ['2','3','4','5','6','7','8','9','J', 'K', 'Q', 'A']
HEARTS = chr(9829)
DIAMONDS = chr(9830)
SPADES = chr(9824)
CLUBS = chr(9827)
suits = [HEARTS,DIAMONDS,SPADES,CLUBS]
def get_deck():
deck = [(suit, card) for suit in suits for card in plain_cards]
shuffle(deck)
return deck
def get_cards_value(cards):
total = 0
aces = []
for card in cards:
if card[1].isdigit():
total += int(card[1])
if card[1] == 'K' or card[1] == 'J' or card[1] == 'Q':
total += 10
if card[1] == 'A' :
total += 11
aces.append('A')
for i in aces:
if total > 21:
total -= 10
return total
def game():
print('Welcome to BLACK JACK')
money = 1000
playing = True
game_on = True
while playing:
if money <= 0:
playing = False
print('Thanks for playing but your money is done come back soon')
else:
bet = input('Stake: ')
if not bet.isdigit():
print('Invalid input')
continue
elif int(bet) > money:
print('You don\'t have enough money')
continue
else:
bet = int(bet)
deck = get_deck()
player_hand = [deck.pop(), deck.pop()]
dealer_hand = [deck.pop(), deck.pop()]
print('Player hand')
print(f'{player_hand} total:{get_cards_value(player_hand)}')
print('Dealer Hand')
print(f'[{dealer_hand[0]}, ###]')
player_total = get_cards_value(player_hand)
dealer_total = get_cards_value(dealer_hand)
while game_on:
if player_total > 21 or dealer_total > 21:
break
choice = input('(S)tand, (D)ouble, (H)it: ')
if choice == 'D':
bet *= 2
money += bet
if choice == 'D' or choice == 'H':
new_card = deck.pop()
player_hand.append(new_card)
break
if choice == 'S':
break
if player_total < 21:
while dealer_total < 17:
new_card = deck.pop()
dealer_hand.append(new_card)
if player_total == 21:
print('You won')
print(f'Player>>{player_hand} total:{get_cards_value(player_hand)}')
print(f'Dealer>>{dealer_hand} total:{dealer_total}')
money += bet
elif dealer_total == 21:
print('You lost')
print(f'Player>>{player_hand} total:{get_cards_value(player_hand)}')
print(f'Dealer>>{dealer_hand} total:{dealer_total}')
money -= bet
elif player_total > dealer_total:
print('You lost')
print(f'Player>>{player_hand} total:{get_cards_value(player_hand)}')
print(f'Dealer>>{dealer_hand} total:{dealer_total}')
money -= bet
elif player_total < dealer_total:
print('You win')
print(f'Player>>{player_hand} total:{get_cards_value(player_hand)}')
print(f'Dealer>>{dealer_hand} total:{dealer_total}')
money += bet
game()
This the output when I enter S,H or D
Traceback (most recent call last):
File "C:/Users/Godfrey Baguma/AppData/Local/Programs/Python/Python39/ssdd.py", line 109, in <module>
game()
File "C:/Users/Godfrey Baguma/AppData/Local/Programs/Python/Python39/ssdd.py", line 82, in game
new_card = deck.pop()
IndexError: pop from empty list
The answer's in the error output there. Specifically, in this block:
if player_total < 21:
while dealer_total < 17:
new_card
dealer_hand.append(new_card)
You didn't set the value of new_card (did you mean to make it new_card = deck.pop()?), so the interpreter has no idea what to do with it and errors out.
The error says that you want to access a variable that is not yet known. There is a bug in your code (line 82 or 83). The program flow can take place in such a way that dealer_hand.append(new_card) is called but new_card is not yet known.
There is an infinite loop:
while dealer_total < 17:
new_card = deck.pop()
dealer_hand.append(new_card)
dealer_total is not updated, so the deck runs out of cards and throws the IndexError.

TypeError: int() argument must be a string, a bytes-like object or a number, not 'tuple'

I am currently five weeks into learning Python, and I am trying to program a very simplified version of Blackjack. I am close to done, but I cannot get past this certain error message:
TypeError: int() argument must be a string, a bytes-like object or a number, not 'tuple'
Here is the code:
import random
print("Welcome to my Black Jack program! Let's play!\n")
def deal_card():
Jack = 10
Queen = 10
King = 10
Ace = 1
cards = [Ace, 2, 3, 4, 5, 6, 7, 8, 9, 10, Jack, Queen, King]
drawn_card = cards[random.randrange(1, 13)]
return drawn_card
def get_player_score():
first_player_card = deal_card()
second_player_card = deal_card()
sum_player_cards = first_player_card + second_player_card
print ("Your card total is: ", sum_player_cards, ".", sep="")
while sum_player_cards < 21:
choice = int(input("Would you like to hit or stay? Enter 1 for 'hit' or 2 for 'stay'. "))
if choice == 1:
new_card = deal_card()
sum_player_cards = sum_player_cards + new_card
print ("Your new total is: ", sum_player_cards, ".", sep="")
elif choice == 2:
return()
else:
print("Please choose 'hit' or stay'.")
choice = input("Would you like to hit or stay? Enter 1 for 'hit' or 2 for 'stay'. ")
if sum_player_cards > 21:
return()
return int(sum_player_cards)
def get_dealer_score():
first_dealer_card = deal_card()
second_dealer_card = deal_card()
sum_dealer_cards = int(first_dealer_card + second_dealer_card)
while sum_dealer_cards <= 16:
another_dealer_card = deal_card()
sum_dealer_cards = sum_dealer_cards + another_dealer_card
if sum_dealer_cards > 16:
print("The dealer's card total is: ", sum_dealer_cards, ".", sep="")
return int(sum_dealer_cards)
def main():
player_score = get_player_score()
dealer_score = get_dealer_score()
if player_score > dealer_score and player_score <= 21:
print("You win!")
elif dealer_score > player_score and dealer_score <= 21:
print("The dealer wins!")
elif dealer_score <= 21 and player_score > 21:
print("You've gone bust! Dealer wins!")
elif dealer_score > 21:
print("The dealer busts! You win!")
main()
I am barely five chapters into Starting Out with Python, 4th ed. So I should only be using principles covered through those first five chapters.
Okay, thanks to #Evert and #Wiggy A., I fixed the return statements in my get_player_score function. Instead of return 0 or return, I realized I needed to change the statements to return sum_player_cards. I thought that return statements could only return values when used at the end of a function definition. But they can be used in if, elif, and else statements as well. Thanks for the input.

Categories

Resources