Creating a Game Using Classes and Objects Practice Project

Hello I am trying to create a blackjack game in python. I am having problems with getting my code to have a player have a hand and a dealer have a hand. I want the game to start dealing cards first so that the player can determine their bet. Perhaps we can do a bet before the cards are dealt as well if we want the game to be more risk based I am willing to be flexible on that point.

https://www.codecademy.com/projects/practice/create-a-game-using-classes-and-objects

Here is my code: hastebin

Can anyone give me any advice?

I would put the code setting up the deck (a Deck object) in an __init__ method.
Also check your indentation for draw and shuffle - those functions should be methods in the Deck class.

Also, the way the indentation is used in the code posted indicates that Chips. Deck, and Player are all inside the Card class.

in the Hand class, you could have an add_card method.

  def add_card(new_card): 
    self.hand.append(new_card)
    self.value += new_card.value
    if new_card.value == "A":
        self.aces += 1

    if (self.value > 21): 
      self.adjust_for_ace()  # redo aces as being 1

Hi Philipandrewstriblin,

Your code looks awesome! I made modifications to the code, and posted the changes to my GitHub. There are some minor changes; however, I tried to implemented all classes and functions from original code.

Feel free to use and modify the code as you wish. I can promise there are probably some bugz and glitches in this code, so if you have any questions, please ask!

1 Like

really wish I could change my name on here to strikeouts27…

anyways I checked out your code and I hope to write code like this someday. I see all the different techniques that I was taught in class used here.

My question is this, how do you determine what is needed to write the next line of code? what questions do you ask yourself? What is your general process? Are you looking to implement a python technique with each line of code?

I know I am a rookie so I am probably easy to impress but I have to admit I really like the technique first style.

A few questions about the code really quickly…
I see that the opening lines showcase methods not in a class. Is that a thing? Are they global methods or something?

I understand the basic concept of while loops. While a condition is applicable the program will run the code until the condition is no longer met. While True-> while what is true? While the method is called? Is while true like a default option?
def getitem → what item?

what is the purpose of def len why do you want python to know the length of the self.cards.

can you explain def display_hand on line 93?

Hey strikeouts27,

First, try the following to change your name.

Change Username

  1. Edit your profile from the main Codecademy site, and change your username there. https://www.codecademy.com/profiles/<your_username>/edit
  2. Next, try logging out of the discussion forum, and logging back in. This forum uses the username from your Codecademy Profile, but needs a logout/login to take the new value.

Let me know if that resolves your issue!

Backjack code

Question: I see that the opening lines showcase methods not in a class. Is that a thing?

Technically, I should have made these functions a part of their associated classes. For example, display_hand() should have been associated with the Hand class, and display_chips should have been associated with the Chips class… I may change this now that you brought it to my attention!

However, to answer your question, there are times when you may include stand-alone methods that are not apart of the class however, may support that class operations. Does that make sense? It depends on how you want to organize your project. Another approach to managing project files would be to store your classes in separate files (or modules) like so:

Blackjack/
├── app/
│   ├── card.py
│   ├── chips.py
│   ├── deck.py
│   ├── hand.py
│   ├── player.py
│   ├── main.py
│   ├── helper_functions.py

So card.py contains the Card class, chips.py contains the Chip class etc. This breaks your project into smaller, easier to manage chunks of code. Then you would import all theses modules into the main.py file like this:

main.py

# main.py

from card import Card
from chips import Chips
from player import Player
from deck import Deck
import helper_functions

def main():
    player = Player()
    dealer = Player()
    
    player_chips = Chips()
    dealer_chips = Chips()
    
    cards = Card()
    deck = Deck()


if __name__ == '__main__':
    main()

The advantage of this is, instead of trying to debug “one” file with 100+ lines of code, you can debug “one-of-many” files that contain 10-15 lines of code. So if you get a TracbackError stemming from Player class, you could go straight to that file, and debug from there. Does that make sense?

Question: How do you determine what is needed to write the next line of code? What questions do you ask yourself? What is your general process? Are you looking to implement a python technique with each line of code?

Pseudocode

Technically, you wrote the majority of this code, you did all the hard work (take pride in that), I just refactored for you it!

However, the best thing to do before programming is to “plan before you code.” Many times programmers start writing code without any planning (I am guilty as well). The problem is, as the project develops it can quickly evolve out of scope, and become difficult to manage. Therefore, plan your project from the start using Psuedocode. Pseudocode for a blackjack game might look like this:

1.  Deal 2 cards to user and dealer
2. Ask player to hit/stay?
3. If hit, deal 2 cards to player
4. If broke or blackjack deliver message
5. If stay, move on to dealers turn

Method for handling dealers turn:

1. Ask dealer to hit/stay?
2. If hit, deal 2 cards 
3. If broke or blackjack deliver message
4. If stay, compare hands
5. If users hand is closer to 21, (user wins)
6. If dealers hand is closer to 21, (user loses)

Once you have this “outline”, and you can see how the logic of your program will work, then you start to code!

One technique would be to write the above psuedocode as comments within your python file, then build your code around these “psuedocode comments”, using it as a guide instructing you what to code next. Does that make sense?

Question: While True-> while what is true? Is while true like a default option?

The while statement takes an expression and executes the loop body while the expression evaluates to (boolean) “True”. The while True statement will run an infinite number of times until the loop is broken (i.e., not True or rather False). For example:

while True:
    pass

This will run an infinite number of times. Which is usually not a desired result . Therefore, you need something to break this loop. Now consider the following code:

player_bust = 0

while True:

    if player_bust == 21:
        break
    else:
        print(player_bust)
    player_bust += 1

So the condition of this code will be True until the player_bust == 21. That is why I used the while True for the condition of the game. I wanted the game to continue UNTIL it needed to end. Does that make sense?

Question: What is the purpose of def len? Why do you want python to know the length of the self.cards.?

Python __len__ is one of the various magic methods. It is basically used to implement the len() function. For example:

class Deck:
    def __init__(self, cards):
        self.cards = cards

    def __len__(self):
        return len(self.cards)

Defining __len__ will now allow you to use len() on a deck object like so.

# create 2 cards
card_1 = 1
card_2 = 2

# Add cards to deck object:
deck = Deck([card_1, card_2])

# Use len on deck object:
print(len(deck))  # 2

If __len__ was not defined, you would get the following error:

TypeError: object of type 'Deck' has no len()

Python __getitem__ is another magic method. It is used for list indexing, dictionary lookup, or accessing ranges of values. For example:

class Deck:
    def __init__(self, cards):
        self.cards = cards

    def __getitem__(self, item):
        return self.cards[item]

Defining __getitem__ will now allow you to index the Deck object class like so.

# create 2 cards
card_1 = 1
card_2 = 2

# Add cards to deck object:
deck = Deck([card_1, card_2])

# Indexing first card
print(deck[0])  # 1

You will notice in the finished code, the Deck class is actually a list of tuples. Therefore, this is the reason why I implemented these 2 magic methods to this class; to give the object class more functionality.

Question: Can you explain def display_hand on line 93?

    def display_hand(self):
        hashtable = {'hearts': 9829, 'diamonds': 9830, 'spades': 9824, 'clubs': 9827}
        return [[i.rank, chr(hashtable.get(i.suit))] for i in self.cards]

The hashtable is mapping the text hearts, diamonds, spades, and clubs to the integer of its Unicode character.
As I mentioned previously, the Deck class is a list of tuples. Actually, it is a list of cards which are made of the Card class - each card is a tuple.

For example, without the hashtable, a Players hand would look like this:

[(7, 'spades'), (6, 'hearts')]

With the hashtable, a Players hand now looks like this:

[(7, '♠'), (6, '♥')]

That is because the hashtable is mapping the suite value to its integer value, which gets converted the Unicode character by using the chr() method. Does that make sense?

Well, I believe I answered all of your questions. If I was unclear in my explanations, or If you have more questions please do not hesitate to ask! If you have any other code project you want me to review or collaborate with you on just reach out to me!

Best regards,

Thank you so much for helping me up to this point. I have broken down the code into separate files as you have suggested. And am working on an outline. While I am working on an outline I have some questions about your reply. okay I have broken the code down into separate files to make it more managable. I think that is a great technique. After reviewing the code it seems that you import the classes of the respective files. You also seem to import helper_functions. What would that be?

On the next few lines you instatiate the class or create objects. I see what you are doing there.

And than I see this:

if name == ‘main’:
main()

what does this do?

Next up I see the def len(self)
return len(self.cards)

by defining len and __get__item you get more functionality. What did you mean by that?

I am getting the ImportError: cannot import name ‘Class’ from ‘card’. In blackjack.py on line 7 it is referencing this… I never said for it to import the name class I wrote from card import Card? (edited)

Is there a possibility I could discuss the code with you for 30 min over zoom or codecademy discord? This is my first python project and I get stuck often.

I am trying to write my first python project blackjack. I was advised to write the program with each class and its methods in a different file so that the code would be more manageable. I divided my code up into smaller files and used import statements.

When I run my code I get the following error message. Chips.place_bet() missing 1 required positional argument. ‘self’. I thought self was, pardon the pun, self explanatory. I do not need to put a value for self. I am wondering if this is an import issue.

I am trying to get my place_bet function to activate so that I can ask the user to input the number of chips for a bet. Can anyone advise me on how to do this?

I have used hastebin to copy my code into a manageable link as I do not know how to upload files into stack overflow. I have also combined all of the code together in one link here separated by the file name.

https://paste.pythondiscord.com/niduheruso

Does anyone have advice for a rookie?

I have tried calling the function and have gotten an error. Nothing else to be honest.

Look at your Player class. It takes 3 parameters (name, chip, hand). However, in your code, you are not passing the correct number of parameters.

def main():
    player = Player('strikeouts27', 500, )
    dealer = Player()

    player_chips = Chips()
    dealer_chips = Chips()

    cards = Card()
    deck = Deck()


if __name__ == '__main__':
    main()

I am trying to get my place_bet function to activate so that I can ask the user to input the number of chips for a bet. Can anyone advise me on how to do this?

The place_bet method is under the Chip class which is now a parameter of the Player. To call it try the following:

seraph = Player('seraph', 500, 'Ace')

# The player object, The chip object, the chip method:
seraph.chips.place_bet()

Does that help answer your question? Let me know if there is anything else I can do to help you out!

Regards,

No this is not for a class assignment. I am just trying to learn the fundamentals of python . I will review your code in github and try to look at it and explain to myself what is going on and make a readme file. After that I plan on trying to recreate the code on my own. And than I plan on doing more python projects in the future as I am a total rookie. Thank you for helping seraph776. I really needed it!

## Basic Usage
``` take this out

Can I have the link to the GitHub repository where the code is again?

Can I have the link to the github repository where we worked on this again? I have just completed the github course and I am looking to use what I learned to collaborate with others.