-2

I'm trying to create a blackjack game in Python. However, when I try to shuffle and deal a card from my deck object, I get an error that states that my 'deck' object has no length. Can anybody help resolve this? Thanks

def deal():
    deck = Deck()
    player = Hand()
    dealer = Hand()
    random.shuffle(deck)
    player.add_card(deck.deal_card())
    player.add_card(deck.deal_card())
    dealer.add_card(deck.deal_card())
    dealer.add_card(deck.deal_card())
    prompt()
user3002315
  • 91
  • 1
  • 6
  • How are you getting the error? Are you trying to call something like `len(deck)`? – Epiglottal Axolotl May 31 '14 at 22:44
  • Can you share the code that is producing the error? Also, you have a `Deck` class, but you don't show an object called `deck`. – Nicholas Flees May 31 '14 at 22:44
  • 1
    If I do `x = Deck()` then `len(x.deck)` I get `52`. – Ant P May 31 '14 at 22:45
  • Here is the full code – user3002315 May 31 '14 at 22:57
  • It could be really helpful for others if you reduce your problem to a minimal example (maybe 20 lines or so) showing only stuff relevant to *reproduce* your issue. I know that it is some work to get such an minimal example, but it greatly increases the value of your question and makes the answers more valueable to community. :) – dst May 31 '14 at 23:12
  • @user3002315 What made you think you needed to post all of your code? The code snippet was fine - you need to *explain the problem.* – Ant P May 31 '14 at 23:22

2 Answers2

1

You are probably trying to use the len function on a Deck object itself as opposed to using it on the instance variable deck of a Deck object. If d is an instance of class Deck, you should call len(d.deck), or even better, implement a getter method for self.deck and use something like len(d.get_deck()).

post-op-edit-edit:

You are trying to call shuffle on the Deck object itself as opposed to the list deck which is stored in your Deck object. Part of the confusion probably comes from the fact that you decided to name the class Deck and its instance variable deck. If you want the list deck, you need to issue deck = Deck().deck in your deal function.

edit in response to comment:

Of course, you cannot call deal_card on the list deck. You can do

def deal():
    deckObject = Deck()
    deckList = deckObject.deck 
    player = Hand()
    dealer = Hand()
    random.shuffle(deckList)
    player.add_card(deckObject.deal_card())
    player.add_card(deckObject.deal_card())
    dealer.add_card(deckObject.deal_card())
    dealer.add_card(deckObject.deal_card())
    prompt()

The notation should hopefully make clear whats the Deck object here and what's the deck list.

timgeb
  • 76,762
  • 20
  • 123
  • 145
  • 2
    why would he need a getter method? – Padraic Cunningham May 31 '14 at 22:55
  • @Padraic Cunningham He does not need a getter method. – timgeb May 31 '14 at 22:56
  • why would it be even better as you suggested? – Padraic Cunningham May 31 '14 at 22:57
  • @Padraic Cunningham To provide an interface for the usage of the class without having to know its internals. IMO, you should only write classes which force you to fumble around in their intestines when you are absolutely sure what you are doing. Does the OP look like such a person? – timgeb May 31 '14 at 23:01
  • A getter method won't solve the ability to call len() on the deck issue. If he really wants to be able to call len(thedeck) on the Deck instance he needs a metaclass... see: http://stackoverflow.com/a/7642535/3651800 – Matt Coubrough May 31 '14 at 23:02
  • deck = Deck.deck() resolved the issue, but now there are other issues. can anyone give more clarification on why it should be deck = Deck.deck() ? – user3002315 May 31 '14 at 23:12
  • After I made the change, there is now an error with the 'deal' function. 'List' object has no attribute 'deal_card'. How can I resolve that? – user3002315 May 31 '14 at 23:14
  • 1
    @user3002315 I tried to explain it in my post, which part is unclear? In short: x = Deck() creates an object which has an instance variable deck. You can access this instance variable with the dot notation, i.e. Deck().deck or x.deck for this example. The shuffle function only works on lists. A Deck object is not a list, but its instance variable deck is. As for your new problem: you need to call deal_card on a Deck object, not on the list deck. – timgeb May 31 '14 at 23:15
  • @user3002315 I edited my post in response to your comment. – timgeb May 31 '14 at 23:22
  • Great so now shuffle and deal work with no errors. Now I'm having problems with my prompt function. I called the prompt function in the last line of my deal function. There seems to be an error with that according to IDLE. Also there seems to be an error with the first 2 print statements in the prompt function. The error message says that 'player' is not defined. but I defined player as a Hand object in the deal function. Any suggestions? – user3002315 Jun 01 '14 at 00:01
  • Is it because I have to call player and dealer as global variables in my prompt function? – user3002315 Jun 01 '14 at 00:02
  • @user3002315 Please make a new question and be more specific this time. We cannot solve all your problems in the comments to my answer. It would also be nice of you to accept one of the answers in this topic if it helped you with your original problem (Deck having no length). – timgeb Jun 01 '14 at 09:24
0
deck = Deck() should be deck = Deck().deck 

Trying random.shuffle on Deck() will result in:

AttributeError: Deck instance has no attribute '__len__'

Deck has no len, where Deck().deck refers to your list of __main__.Card instance's which has a length.

In [42]: d = Deck()

In [43]: d.deck.__len__() # self.deck has a __len__() as it is a list of instances
Out[43]: 52


In [44]: d = Deck()

In [45]: d.__len__()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-45-c2cc108c72f0> in <module>()
----> 1 d.__len__()

AttributeError: Deck instance has no attribute '__len__'

random.shuffle Shuffle the sequence x in place. The optional argument random is a 0-argument function returning a random float in [0.0, 1.0); by default, this is the function random(). Note that for even rather small len(x), the total number of permutations of x is larger than the period of most random number generators; this implies that most permutations of a long sequence can never be generated.

Notice len(x).

Padraic Cunningham
  • 176,452
  • 29
  • 245
  • 321